EF代码优先:具有多个多对一关系的实体类型

马克·米勒

考虑3类:PersonCompany,和File

Person并且Company是完全不同的,不相关的,但他们每个人都有的集合File对象。无论它属于哪个实体,File都始终具有相同的结构。

这个问题是关于如何对File可能具有的多个多对一关系进行最佳建模在这种情况下,File可以与Person或与Company(但在同一实例中不能同时存在)多对一关系


方法1:

class Person
{
    public int Id {get;set;}
    public ICollection<File> Files {get;set;}
}
class Company
{
    public int Id {get;set;}
    public ICollection<File> Files {get;set;}
}
class File
{
    public int Id {get;set;}
    public string Path {get;set;}
}

/* 
    EF Generates:
    -----------------
    Table: Person (Id)
    Table: Company (Id)
    Table: File (Id, Path, Person_Id, Company_Id)
*/

从代码优先的角度来看,这似乎是最简单,最直接的方法,也是我最喜欢的方法。问题在于表File,该具有Person_Id和Company_Id的可空字段。从数据库设计的角度来看,这似乎是错误的,考虑到两个字段中只有一个具有值,而另一个字段始终为null。在文件集合中添加更多的类会使问题更加严重。


方法二:

class Person
{
    public int Id {get;set;}
    public ICollection<PersonFile> Files {get;set;}
}
class Company
{
    public int Id {get;set;}
    public ICollection<CompanyFile> Files {get;set;}
}
class File
{
    public int Id {get;set;}
    public string Path {get;set;}
}
class PersonFile
{
    public Person Person {get;set;}
    public File File {get;set;}
}
class CompanyFile
{
    public Company Company {get;set;}
    public File File {get;set;}
}

/*
    EF Generates:
    ------------------
    Table: Person (Id)
    Table: Company (Id)
    Table: File (Id, Path)
    Table: PersonFile (Person_Id, File_Id)
    Table: CompanyFile (Company_Id, File_Id)
*/

这完成了与方法1相同的操作,并且更接近于我在DB First设计中传统上所做的事情。但是它需要另外两个我真的不需要的类...还是我呢?我想这就是这个问题的重点...


在设计Code First Entity Framework应用程序时,我是否需要担心数据库架构?是否可以像方法1那样优先考虑代码/模型简单性而不是数据库设计?还是应该像方法2那样考虑数据库设计来编写类?

哈拉德·科普普斯(Harald Coppoolse)

是的,您确实需要担心数据库架构,

也许在您的示例中没有特别说明,但特别是在使用继承时。

这样做的原因是因为关系数据库(特别是SQL)不了解继承的概念。在设计时间表时,您必须决定哪种方法适合您的需求。

例如,在创建学校数据库时,您可能会设计一个具有姓名,地址,电话号码等的人员。

您会发现“学生”和“老师”都有名字,地址等。与普遍的看法相反,您会发现“学生”和“老师”都是人。

最常用的三种继承方法。

  • 每个层次结构的TPH表:一个用于所有派生类的大表,其中教师和学生的所有属性都放在一个表中
  • TPT每种类型的表格:教师/学生/人员在不同的表格中。老师和学生对他们的个人数据有外键
  • 每个具体班级的TPC表:教师表包含教师和人员属性的所有数据,而学生表包含学生和人员属性的所有数据。

您将使用哪种方式取决于共享属性的比例以及“学生”与“老师”之间的差异。如果它们几乎具有所有相同的属性,那么一个表的TPH就足够了。

但是,如果有很多教师没有的学生属性,则该表将有很多空值供教师使用。如果与学生人数相比没有很多老师,这可能不是问题,否则浪费空间可能是一个需要考虑的问题。

要考虑的另一件事是该方案将多久更改一次。如果您确实确定教师将永远是人,并且学生与教师之间的共同属性(=人属性)将始终是共同的,那么TPH可能会更好:三个表:人/教师/学生。

另一方面,如果您认为只要需要一个学生,就始终需要他的Person数据,那么TPH总是会导致加入。也许在这种情况下,TPC可能是一个更好的选择。但是,如果您经常只需要学生的特定数据而没有他的“人”数据,则TPC可能不是一个好选择

如果您不关心该方案,您会发现Entity Framework将选择TPH:一个包含所有学生和老师以及学生和老师的所有属性的大表。

如果您不希望这样做,则必须告诉EF您想要其他方法之一。使用流畅的API即可轻松完成此操作

如何做到这一点在Code-First中的继承策略中有很好的描述。

顺便说一句,完整的文章对我开始使用EF进行编程非常有帮助-代码优先

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

一对零或一对一关系的实体框架(EF)代码优先级联删除

来自分类Dev

如何使用休眠Lucene搜索具有多对一关系的实体

来自分类Dev

实体框架与相同实体类型但具有不同关系类型的多对多关系

来自分类Dev

多对多关系EF代码优先

来自分类Dev

EF代码优先:使用数据注释设置可选的一对一关系

来自分类Dev

使用Thymeleaf发布具有多对一关系的数据

来自分类Dev

代码优先实体框架具有多对多的多个集合

来自分类Dev

实体框架代码优先一对一关系

来自分类Dev

具有TPH继承的实体类型到多个表的EF映射属性

来自分类Dev

symfony3:为具有多对一关系的列的实体创建表单

来自分类Dev

EF代码优先:具有多个多对一关系的实体类型

来自分类Dev

Symfony主义查询生成器查找具有多对一关系的实体

来自分类Dev

EF Core:无法跟踪实体类型的实例,因为另一个具有相同键值的实例

来自分类Dev

Django,与抽象实体多对一关系

来自分类Dev

按日期获取具有多对一关系的多个表的最后一条记录

来自分类Dev

Zend2-Doctrine2:创建具有多对一关系的新实体

来自分类Dev

具有相同类型导航属性集合的EF6代码第一实体-如何告诉EF是什么关系?

来自分类Dev

相同实体类型代码的多对多关系首先

来自分类Dev

具有两个多对一关系的实体关系

来自分类Dev

正确的Linq查询使用代码优先实体框架生成的具有多对多关系的对象

来自分类Dev

如何使用实体框架代码优先在两个实体之间具有多个一对多关系

来自分类Dev

在Postgresql中创建具有多对一关系的表

来自分类Dev

实体框架代码优先关系:一对多到多个实体

来自分类Dev

实体框架6:具有继承关系的一对一关系

来自分类Dev

代码优先的可选一对一关系

来自分类Dev

具有TPH继承的实体类型到多个表的EF映射属性

来自分类Dev

EF代码优先与不同PK类型的多对多关系

来自分类Dev

当表单具有实体类型时,Symfony3多对多现实

来自分类Dev

如何正确连接具有多对一关系的表

Related 相关文章

  1. 1

    一对零或一对一关系的实体框架(EF)代码优先级联删除

  2. 2

    如何使用休眠Lucene搜索具有多对一关系的实体

  3. 3

    实体框架与相同实体类型但具有不同关系类型的多对多关系

  4. 4

    多对多关系EF代码优先

  5. 5

    EF代码优先:使用数据注释设置可选的一对一关系

  6. 6

    使用Thymeleaf发布具有多对一关系的数据

  7. 7

    代码优先实体框架具有多对多的多个集合

  8. 8

    实体框架代码优先一对一关系

  9. 9

    具有TPH继承的实体类型到多个表的EF映射属性

  10. 10

    symfony3:为具有多对一关系的列的实体创建表单

  11. 11

    EF代码优先:具有多个多对一关系的实体类型

  12. 12

    Symfony主义查询生成器查找具有多对一关系的实体

  13. 13

    EF Core:无法跟踪实体类型的实例,因为另一个具有相同键值的实例

  14. 14

    Django,与抽象实体多对一关系

  15. 15

    按日期获取具有多对一关系的多个表的最后一条记录

  16. 16

    Zend2-Doctrine2:创建具有多对一关系的新实体

  17. 17

    具有相同类型导航属性集合的EF6代码第一实体-如何告诉EF是什么关系?

  18. 18

    相同实体类型代码的多对多关系首先

  19. 19

    具有两个多对一关系的实体关系

  20. 20

    正确的Linq查询使用代码优先实体框架生成的具有多对多关系的对象

  21. 21

    如何使用实体框架代码优先在两个实体之间具有多个一对多关系

  22. 22

    在Postgresql中创建具有多对一关系的表

  23. 23

    实体框架代码优先关系:一对多到多个实体

  24. 24

    实体框架6:具有继承关系的一对一关系

  25. 25

    代码优先的可选一对一关系

  26. 26

    具有TPH继承的实体类型到多个表的EF映射属性

  27. 27

    EF代码优先与不同PK类型的多对多关系

  28. 28

    当表单具有实体类型时,Symfony3多对多现实

  29. 29

    如何正确连接具有多对一关系的表

热门标签

归档