【问题标题】:Entity Framework tpc inheritance model creating实体框架 tpc 继承模型创建
【发布时间】:2016-03-26 14:23:29
【问题描述】:

我正在使用 Entity Framework 6 和 TPC 继承策略

每个实体的基类如下:

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

    public string OType
    {
        get;
        set;
    }

    public DateTime Date { get; set; }
}

这是我的模型创建代码:

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);
} 

如您所见,我正在映射每个实体及其名称,并且我有 200 个实体。有没有更简单的方法来做到这一点?

【问题讨论】:

  • 拥有这么多实体,TPC 不是正确的方法。使用基类并分别映射每个实体。
  • 所有这些类的基类是什么?
  • @AlbertoMonteiro 我添加了基类,请参阅我的编辑
  • @brtb 如果你把这个类抽象化,你就不需要使用这个配置了,会容易很多。你需要把 MainObj 变成一张桌子吗?
  • IMO,如果我发现自己正在考虑 200 个子类(表),我可能会重新考虑数据模型。

标签: c# entity-framework inheritance database-design


【解决方案1】:

是的,有。

选项 1

如果您不需要 MainObj 类成为表格,那么只需将其设为 abstract 并删除将表格名称复数的约定,如下所示:

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
}

选项 2

如果 MainObj 必须是一个表,那么您可以使用反射为您做映射的东西,并删除复数表名的约定,如下所示:

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(); });
    }
}

我创建了一个通用的 MapInheritedProperties 方法,它告诉 EF MapInheritedProperties 到作为通用类型的表。

使用反射后,我们从当前类中获取此方法,然后查找所有继承自 MainObj 的类型,对每个我们调用 MapInheritedProperties 的类型,然后魔术就完成了。

【讨论】:

    猜你喜欢
    • 2016-10-28
    • 2023-03-23
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多