考虑3个课程:Person
,Company
和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。使用文件集添加更多类会进一步加剧这个问题。
方法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第一次设计中传统做的事情。但它需要两个额外的课程,我真的不需要......或者我需要?我想这就是这个问题的重点...
在设计Code First Entity Framework应用程序时,我是否需要担心数据库架构?我可以像在方法1中那样优先考虑数据库设计中的代码/模型简单性吗?或者我应该在编写带有数据库设计的类时,如方法2中那样?
答案 0 :(得分:1)
是的,你必须担心数据库架构,
在您的示例中可能没有特别说明,尤其是在使用继承时。
原因是因为关系数据库(特别是SQL)不知道继承的概念。在设计您的日程安排时,您必须确定哪种方法适合您的需求。
例如,在创建学校数据库时,您可能会设计一个具有姓名,地址,电话号码等的人员。
你会发现学生和教师都有姓名,地址等。与流行的看法相反,你会发现学生和老师都是人。
最常用的是三种继承方法。
无论您使用哪种方法,都取决于共享属性的比例以及学生和教师之间的差异。如果他们几乎所有的属性都有共同点,那么带有一个表的TPH就足够了。
但是,如果教师没有很多学生宿舍,那么教师会有很多空值。如果没有很多教师与学生人数相比,这可能不是问题,否则浪费空间可能是一个需要考虑的事项。
另一件需要考虑的事情是该计划的变化频率。如果你真的确定教师永远是人,并且学生和教师之间的共同属性(=人物属性)总是很常见,那么TPH可能会更好:三个表:人/教师/学生。
另一方面,如果您认为每当您需要学生时,您将始终需要他的人员数据,那么TPH将始终导致加入。也许在那种情况下,TPC可能是更好的选择。但是,如果您经常只需要学生的特定数据而没有他的人员数据,那么TPC可能不是一个好选择
如果您不关心该计划,您会发现实体框架将选择TPH:一个大表,所有学生和教师都拥有学生和教师的所有属性。
如果你不想要这个,你必须告诉EF你想要其他方法之一。这可以使用 fluent API
轻松完成如何做到这一点在Inheritance Strategy in Code-First
中描述得相当不错顺便说一下,完整的文章对我开始使用EF代码开始编程很有帮助