Generic classes in EF Code First

徘徊边缘 提交于 2019-12-08 07:56:31

问题


I’m trying to incorporate EF in my application. I use EF6 and Code First. My object model has some generic classes and it seems that Code First accepts it partially (tables and columns are generated correctly).

Below an example:

public class Group : TimeableObject<GroupTimeline> {}

public class GroupTimeline : TimelineBase
{
    public GroupTimeline() { }
    public string Name {get; set;}
}

public abstract class TimelineBase
{
    public int Id { get; set; }
    public DateTime BeginDate { get; set; }
    public DateTime EndDate { get; set; }
}

public abstract class TimeableObject<T>
    where T : TimelineBase
{
    private DateTime? _snapshotDate;

    public TimeableObject()
    {
        Timelines = new List<T>();
    }

    public int Id { get; set; }
    public DateTime BeginDate { get; set; }
    public DateTime EndDate { get; set; }

    public List<T> Timelines { get; set; }

    public DateTime SnapshotDate
    {
        get { //some logic.. }
        set { _snapshotDate = value; }
    }

    public T Timeline
    {
        get { //some logic.. }
    }
}

Through fluent API I configured the inheritance as TPC. So I expect a table Groups and a table GroupTimeline with a foreign key to Groups in GroupTimeline.

First of all, the generated database looks correct except for the identity. The strange thing about this is that EF sees the Id property in e.g. Group and generates a PK in the database. Althought without an identity. The same for the Id property in the TimelineBase class. Second, I don't want the property SnapshotDate to be mapped. Through fluent API I was not able to reach this. Here I get an exception telling me that the complete class is ignored or is a generic. So I assume that EF does not support generic classes although the database is generated correctly (not the identity). What's the story behind this?? With the use of data annotations I fixed my issues. I can get an identity with the attributes (on the Id property):

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

and I can prevent mapping the SnapshotDate property with:

[NotMapped]

below my fluent configuration:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Group>().Map(m =>
        {
            m.MapInheritedProperties();
        });
        modelBuilder.Entity<GroupTimeline>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Group_Timeline");
        });

      modelBuilder.Entity<TimeableObject<TimelineBase>>().HasKey(m => m.Id).Property( p => p.Id ).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
      modelBuilder.Entity<TimeableObject<TimelineBase>>().Ignore(m => m.SnapshotDate);
      modelBuilder.Entity<TimelineBase>().HasKey(m => m.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }

This throw's an exception:

The type 'Data.DataObjectModel.TimeableObject`1[Data.DataObjectModel.TimelineBase]' 
was not mapped. Check that the type has not been explicitly excluded by using the 
Ignore method or NotMappedAttribute data annotation. Verify that the type was 
defined as a class, is not primitive or generic, and does not inherit from 
EntityObject.

Regards, Daniel Kaya

来源:https://stackoverflow.com/questions/23871346/generic-classes-in-ef-code-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!