简体   繁体   中英

Entity Framework tpc inheritance model creating

I m using Entity Framework 6 and TPC inheritance strategy

My base class for every entity is the following :

public class MainObj : IdentifiedModel
{
    public int Status
    {
        get;
        set;
    }

    public string OType
    {
        get;
        set;
    }

    public DateTime Date { get; set; }
}

This is my model creating code:

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

        modelBuilder.Entity<Entity2>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Entity2");
        });

        modelBuilder.Entity<Entity3>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Entity3");
        });

        modelBuilder.Entity<Entity4>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Entity4");
        });

        base.OnModelCreating(modelBuilder);
} 

As you can see I'm mapping every entity with its name and I have 200 entities. Is there any easier way to do this?

Yes, there is.

Option 1

If you dont need the MainObj class become a table, so just make it abstract and the remove a convention that pluralize table name, like that:

public abstract class MainObj
{
    public int Status { get; set; }

    public string OType { get; set; }

    public DateTime Date { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    //base.OnModelCreating(modelBuilder); you dont need this line, it does nothing
}

Option 2

If MainObj must be a table, so you can use reflection to do mapping stuff for you and remove a convention that pluralize table name, like this:

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        var methodInfo = GetType().GetMethod("MapInheritedProperties");

        var type = typeof(MainObj);
        foreach (var descendantType in type.Assembly.GetTypes().Where(t => t.IsAssignableFrom(type)))
        {
            var mapInheritedProperties = methodInfo.MakeGenericMethod(descendantType);
            mapInheritedProperties.Invoke(null, new object[] { modelBuilder });
        }

        //base.OnModelCreating(modelBuilder); you dont need this line, it does nothing
    }

    private static void MapInheritedProperties<T>(DbModelBuilder modelBuilder) where T : class
    {
        modelBuilder.Entity<T>().Map(m => { m.MapInheritedProperties(); });
    }
}

I created a MapInheritedProperties method that is generic, that tell EF to MapInheritedProperties to table that is the generic type.

After using reflection we get this method from current class, and then we look for all types that inherit from MainObj , for each one we call MapInheritedProperties, and then the magic is done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM