C# 代码优先,EF4.1:用数据库映射以下类的最佳方法是什么。。。?

C# 代码优先,EF4.1:用数据库映射以下类的最佳方法是什么。。。?,c#,.net,entity-framework,code-first,C#,.net,Entity Framework,Code First,亲爱的专业开发人员社区 我想先弄清楚如何使用代码正确地进行映射 假设有几个类。一个容器类、一个基类和几个子类 基类: public class Base { public int Id { get; set; } } 子类: public class FirstDescendant { public string FirstProperty { get; set; } } public class SecondDescendant { public int SecondPro

亲爱的专业开发人员社区

我想先弄清楚如何使用代码正确地进行映射

假设有几个类。一个容器类、一个基类和几个子类

基类:

public class Base {

 public int Id { get; set; }

}
子类:

public class FirstDescendant {

 public string FirstProperty { get; set; }

}

public class SecondDescendant {

 public int SecondProperty { get; set; }

}

public class ThirdDescendant {

 public int ThirdProperty { get; set; }

}
容器类:

public class Container {

 public int Id { get; set; }

 public ICollection<FirstDescendant> FirstDescendants { get; set; }

 public ICollection<SecondDescendant> SecondDescendants { get; set; }

 public ICollection<ThirdDescendant> ThirdDescendants { get; set; }

}
公共类容器{
公共int Id{get;set;}
公共ICollection第一子代{get;set;}
公共ICollection第二子体{get;set;}
公共ICollection第三个搜索对象{get;set;}
}
默认情况下,在创建DbContext并运行代码后,我会得到两个具有以下结构的表:

容器

身份证

基础

身份证

第一财产

集装箱编号1

第二财产

集装箱Id2

第三十财产

集装箱Id3

所以我得到了一个名为Base的表,其中包含三个具有相同外键角色的相同字段

现在问题是:

  • 我不喜欢那种冗余。专业团体如何评价这种情况,这正常吗

  • 我能换这个吗?我能得到一个更清晰的数据库结构吗

  • 映射这些类的最佳方法是什么

  • 我已经发表了,但我仍然关心这个问题


    感谢您的回答和关注。

    默认情况下,数据库中的表结构是正常的,每层次表(TPH)映射的结果。将类层次结构映射到关系数据库表是默认策略。在该策略中,所有派生类的属性都合并到一个表中,并且仅通过表中的鉴别器列来区分类型

    如果您希望层次结构中的每个类都有一个单独的表,可以使用每类型表(TPT)策略。但这不是默认值,您必须通过数据注释明确指定这一点

    [Table("FirstDescendants")]
    public class FirstDescendant : Base
    {
        public string FirstProperty { get; set; }
    }
    // the same with the other derived classes
    
    。。。或使用流利的代码:

    modelBuilder.Entity<FirstDescendant>().ToTable("FirstDescendants");
    // the same with the other derived classes
    
    modelBuilder.Entity().ToTable(“第一代后代”);
    //与其他派生类相同
    
    通过这种方式,您将获得一个用于
    Base
    类的表,该表仅包含该类的属性(在您的示例中仅为
    Id
    ),以及具有派生类属性的单独表
    firstsubstands
    等等。这些表通过外键关系链接,EF设法从这两个表中加载所需的列,以具体化所查询类型的对象

    您可以在此处找到EF如何映射类层次结构的几种策略的介绍:

    编辑

    在我看来,TPT是将派生类映射到关系表的更干净的方法。TPH要求您在数据库中具有可为空的列,仅用于您可能希望在模型中具有所需属性的映射。但另一方面,TPH的性能可能更高,因为查询不需要连接不同的表

    一个可能的经验法则是:

    • 如果大多数属性都在基类中,而派生类只添加了一些附加属性,那么可以使用TPH

    • 如果基类不包含或仅包含少数属性,并且大多数属性都在派生类中,则使用TPT

    但是,这些方法的正反两面——也是每种混凝土类别的第三个表(TPC)——要好得多,并在上面的链接文章系列中进行了详细解释