2016-03-14 66 views
1

考虑3类:Person,CompanyFileEF代码优先:具有多个多对一关系的实体类型

PersonCompany是完全不同且无关的,但它们每个都有一个File对象的集合。无论它属于哪个实体,File总是具有相同的结构。

这个问题是关于如何最好地模拟File可以具有的多对多关系;在这种情况下,File可以与PersonCompany(但不在同一实例中)具有多对一的关系。


方法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的无效字段。从数据库设计的角度来看,这看起来是错误的,考虑到两个字段中只有一个字段会有值,而另一个永远是空的。使用文件集合添加更多类会更加激化问题。


方法2:

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传统设计完成。但它需要两个额外的类,我真的不需要......或者我呢?我想这是这个问题的点...


当设计守则第一实体框架应用程序,做我需要担心的数据库模式?在方法1中,我可以优先考虑数据库设计的代码/模型简化吗?还是应该像方法2一样,在脑海中编写数据库设计类?

回答

1

是你必须要担心的数据库架构,

也许没有具体的例子,但使用继承时尤其如此。

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

例如,创建一个学校数据库时,你可能会设计的人,谁都有一个名称,地址,电话号码等

你会发现,学生和老师有姓名,地址等等。与流行的观点相反,你会发现学生和老师都是人。

最常用的三种继承方法。

  • TPH每一个分层表:一个大表的所有派生类的人,在一个表
  • TPT表每种类型教师的所有属性和学生:教师/学生/人在单独的表格中。教师和学生对他们的个人资料有一个外键
  • TPC每个具体类的表:包含教师和个人属性的所有数据的教师表和包含学生和个人属性的所有数据的学生表。

无论你使用哪一个取决于共享属性的比例以及学生和教师之间的差异。如果他们几乎拥有所有的属性,那么带有一张桌子的TPH就足够了。

但是,如果有很多教师不具备的学生属性,那么该表对教师而言将会有很多空值。如果与学生人数相比,教师不多,这可能不成问题,否则浪费空间可能是一个需要考虑的问题。

要考虑的另一件事是该计划将多久改变一次。如果你真的确定教师永远是人,而且学生和教师之间的共同属性(=个人属性)将永远是常见的,那么TPH可能会更好:三个表格:人员/教师/学生。另一方面,如果你认为每当你需要一个学生时,你总是需要他的人物数据,那么TPH总是会导致一个加入。也许在这种情况下,TPC可能是更好的选择。然而,如果你经常只需要学生的特定数据而没有他的个人数据,TPC可能不是一个好选择

如果你不关心这个计划,你会发现实体框架会选择TPH:一个大的所有学生和老师均拥有学生和老师的所有特性。

如果你不想要这个,你必须告诉EF你想要其他方法之一。这是很容易使用流利的API

如何做到这一点是相当不错的Inheritance Strategy in Code-First

描述顺便说做的,完整的文章是非常有益的,我开始使用EF编程 - 代码第一

+0

谢谢!响应和链接都非常有帮助! –

相关问题