This is a migrated thread and some comments may be shown as answers.

Dictionary in base class

5 Answers 77 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Sergey
Top achievements
Rank 1
Sergey asked on 27 Jun 2013, 04:42 PM
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>();
    }
}





5 Answers, 1 is accepted

Sort by
0
PetarP
Telerik team
answered on 02 Jul 2013, 03:07 PM
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.
0
Sergey
Top achievements
Rank 1
answered on 03 Jul 2013, 10:39 AM
This code compiles without errors, but does not create the table ClassDetails
0
PetarP
Telerik team
answered on 09 Jul 2013, 02:37 PM
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.
0
Sergey
Top achievements
Rank 1
answered on 10 Jul 2013, 10:04 AM
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.
0
PetarP
Telerik team
answered on 15 Jul 2013, 12:33 PM
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.
Tags
General Discussions
Asked by
Sergey
Top achievements
Rank 1
Answers by
PetarP
Telerik team
Sergey
Top achievements
Rank 1
Share this question
or