Dictionary in base class

6 posts, 0 answers
  1. PAG
    PAG avatar
    5 posts
    Member since:
    Aug 2012

    Posted 27 Jun 2013 Link to this post

    Have exception when map dictionary frome base class:

    Telerik.OpenAccess.Exceptions.MetadataException was unhandled
      HResult=-2146233088
      Message=Mapping for field '<Details>k__BackingField' is specified in the file 'config', but the field is not present in the class 'MyNamespace.Class'. --> FromMetadataContainer/namespace[MyNamespace]/class[Class]/field[<Details>k__BackingField]
      Source=Telerik.OpenAccess
      CanRetry=true
      ClassName=MyNamespace.Class
      Column=0
      Context=--> FromMetadataContainer/namespace[MyNamespace]/class[Class]/field[<Details>k__BackingField]
      ErrorId=2
      FieldName=<Details>k__BackingField
      FileName=config
      IsWarning=false
      Line=0
      StackTrace:
           в Telerik.OpenAccess.SPI.Backends.ThrowException(Exception e)
           в OpenAccessRuntime.ExceptionWrapper.Throw()
           в OpenAccessRuntime.storagemanager.StorageManagerFactoryBuilder.createSmfForURL()
           в OpenAccessRuntime.storagemanager.StorageManagerFactoryBuilder.createStorageManagerFactory()
           в OpenAccessRuntime.DataObjects.tools.ant.DataObjectsTaskBase.execute()
           в OpenAccessRuntime.DataObjects.tools.ant.SchemaMigrationTask.execute()
           в OpenAccessRuntime.OpenAccessSchemaAdapter.CreateUpdateDDLScript(SchemaUpdateProperties schemaUpdateProps)
           в OpenAccessRuntime.SchemaHandlerImpl.Telerik.OpenAccess.ISchemaHandler.CreateUpdateDDLScript(SchemaUpdateProperties props)
           в MyNamespace.DataModelContext.UpdateSchema() в c:\PAGGIT\testProj\ForTests\Program.cs:строка 95
           в MyNamespace.Programm.Main() в c:\PAGGIT\testProj\ForTests\Program.cs:строка 20
           в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           в System.Threading.ThreadHelper.ThreadStart()
      InnerException:
    Code:
        protected override IList<MappingConfiguration> PrepareMapping()
        {
            List<MappingConfiguration> preparedConfigs = new List<MappingConfiguration>();
     
            //Маппинг базового класса
            MappingConfiguration<BasicDataBaseItem> basicDataBaseItemConfiguration = new MappingConfigurationWithNamingRules<BasicDataBaseItem>();
            basicDataBaseItemConfiguration.MapType(p => new
            {
                UniqID = p.UniqID,
                Name = p.Name,
                Description = p.Description,
                CreateDateTime = p.CreateDateTime,
                UpdateDateTime = p.UpdateDateTime
     
            }).Inheritance(InheritanceStrategy.Horizontal);
            basicDataBaseItemConfiguration.HasProperty(p => p.Name).IsNotNullable();
            basicDataBaseItemConfiguration.HasProperty(p => p.CreateDateTime).IsCalculatedOn(DateTimeAutosetMode.Insert);
            basicDataBaseItemConfiguration.HasProperty(p => p.UpdateDateTime).IsCalculatedOn(DateTimeAutosetMode.InsertAndUpdate);
     
     
            MappingConfiguration<Class> classConfiguration = new MappingConfiguration<Class>();
            classConfiguration.MapType(p => new
            {
                UniqID = p.UniqID,
                ParentClassID = p.ParentClassID,
            }).ToTable("Class");
            classConfiguration.MapType().ToTable("Class");
            classConfiguration.HasProperty(p => p.UniqID).IsIdentity().ToColumn("UniqID");
            classConfiguration.HasAssociation(p => p.ParentClass).HasConstraint((p, c) => p.ParentClassID == c.UniqID);
            classConfiguration.HasProperty(p => p.Details).WithDictionaryKey("Key", "nvarchar(255)").WithDictionaryValue("Value", "nvarchar(Max)").WithForeignKey("ClassId", "uniqueidentifier").WithTable("ClassDetails");
     
            preparedConfigs.Add(basicDataBaseItemConfiguration);
            preparedConfigs.Add(classConfiguration);
     
            return preparedConfigs;
        }
    public abstract class BasicDataBaseItem
    {
        public Guid UniqID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public DateTime CreateDateTime { get; set; }
        public DateTime UpdateDateTime { get; set; }
        public IDictionary<string, string> Details { get; set; }
     
    }
    public class Class : BasicDataBaseItem
    {
        public Class ParentClass { get; set; }
        public IList<Class> ChildClasses { get; set; }
        public Guid? ParentClassID { get; set; }
        public Guid UniqID { get; set; }
        public Class()
        {
            ChildClasses = new List<Class>();
        }
    }





  2. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 02 Jul 2013 Link to this post

    Hello Sergey,

     The problem here lies in the fact that our metadata compilation works based on your fields and not your properties. As such we are trying to find each and every field in the class that you have defined mapping for and following that logic we are attempting to find the backing field of your dictionary property inside Class while it actually is in your base class. In order to correctly navigate our metadata compilation algorithm you need to specify the correct field name with its full name, including the base class. In order to do that you will need to add an actual field for your dictionary rather than counting on the auto property.
    In the end your code should look something like that:

    rotected override IList<MappingConfiguration> PrepareMapping()
            {
                List<MappingConfiguration> preparedConfigs = new List<MappingConfiguration>();
     
                //Маппинг базового класса
                MappingConfiguration<BasicDataBaseItem> basicDataBaseItemConfiguration = new MappingConfiguration<BasicDataBaseItem>();
                basicDataBaseItemConfiguration.MapType(p => new
                {
                    UniqID = p.UniqID,
                    Name = p.Name,
                    Description = p.Description,
                    CreateDateTime = p.CreateDateTime,
                    UpdateDateTime = p.UpdateDateTime
     
                }).Inheritance(InheritanceStrategy.Horizontal);
                basicDataBaseItemConfiguration.HasProperty(p => p.Name).IsNotNullable();
                basicDataBaseItemConfiguration.HasProperty(p => p.CreateDateTime).IsCalculatedOn(DateTimeAutosetMode.Insert);
                basicDataBaseItemConfiguration.HasProperty(p => p.UpdateDateTime).IsCalculatedOn(DateTimeAutosetMode.InsertAndUpdate);
     
     
                MappingConfiguration<Class> classConfiguration = new MappingConfiguration<Class>();
                classConfiguration.MapType(p => new
                {
                    UniqID = p.UniqID,
                    ParentClassID = p.ParentClassID,
                }).ToTable("Class");
                classConfiguration.MapType().ToTable("Class");
                classConfiguration.HasProperty(p => p.UniqID).IsIdentity().ToColumn("UniqID");
                classConfiguration.HasAssociation(p => p.ParentClass).HasConstraint((p, c) => p.ParentClassID == c.UniqID);
                classConfiguration.HasProperty(p => p.Details).HasFieldName("BasicDataBaseItem.details").WithDictionaryKey("Key", "nvarchar(255)").WithDictionaryValue("Value", "nvarchar(Max)").WithForeignKey("ClassId", "uniqueidentifier").WithTable("ClassDetails");
     
                preparedConfigs.Add(basicDataBaseItemConfiguration);
                preparedConfigs.Add(classConfiguration);
     
                return preparedConfigs;
            }
        }
     
        public abstract class BasicDataBaseItem
        {
            public Guid UniqID { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public DateTime CreateDateTime { get; set; }
            public DateTime UpdateDateTime { get; set; }
            private IDictionary<string, string> details = new Dictionary<string, string>();
            public IDictionary<string, string> Details
            {
                get
                {
                    return this.details;
                }
                set
                {
                    this.details = value;
                }
            }
     
        }
        public class Class : BasicDataBaseItem
        {
            public Class ParentClass { get; set; }
            public IList<Class> ChildClasses { get; set; }
            public Guid? ParentClassID { get; set; }
            public Guid UniqID { get; set; }
            public Class()
            {
                ChildClasses = new List<Class>();
            }
        }

    Regards,
    Petar
    Telerik
    OpenAccess ORM Q2 2013 brings you a more powerful code generation and a unique Bulk Operations support with LINQ syntax. Check out the list of new functionality and improvements shipped with this release.
  3. DevCraft banner
  4. PAG
    PAG avatar
    5 posts
    Member since:
    Aug 2012

    Posted 03 Jul 2013 Link to this post

    This code compiles without errors, but does not create the table ClassDetails
  5. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 09 Jul 2013 Link to this post

    Hi Sergey,

     Strangely enough I was not able to reproduce that behaviour on my side. Do you have any additional classes in your mapping configuration? It is not impossible that due to an error in the definition in other parts of your matadata our schema migration mechanism might be influencing this collection as well?
    Additionally can you try defining the dictionary in the base class like this:

    basicDataBaseItemConfiguration.HasProperty(p => p.Details).HasFieldName("_details").WithDictionaryKey("Key", "nvarchar(255)").WithDictionaryValue("Value", "nvarchar(Max)").WithForeignKey("ClassId", "uniqueidentifier").WithTable("ClassDetails");

    and see if that has any effect.

    Regards,
    Petar
    Telerik
    OpenAccess ORM Q2 2013 brings you a more powerful code generation and a unique Bulk Operations support with LINQ syntax. Check out the list of new functionality and improvements shipped with this release.
  6. PAG
    PAG avatar
    5 posts
    Member since:
    Aug 2012

    Posted 10 Jul 2013 Link to this post

    hi,
    i have only this two clases. 
    I try, what you write. it is work and creates table ClassDeatails, but it is not work with two inheritor classes.
  7. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 15 Jul 2013 Link to this post

    Hi Sergey,

     Seems that we indeed have a problem in the case where the dictionary is in the base class. Unfortunately there is no workaround as of now and the only way for you to continue your work is to put the dictionary in the inheritor instead. We will try to fix this bug for our next public release.
    Please find your Telerik points updated for bringing that bug to our attention.

    Regards,
    Petar
    Telerik
    OpenAccess ORM Q2 2013 brings you a more powerful code generation and a unique Bulk Operations support with LINQ syntax. Check out the list of new functionality and improvements shipped with this release.
Back to Top
DevCraft banner