11.翻译系列:在EF 6中配置一对零或者一对一的关系【EF 6 Code-First系列】
原文链接:
这里,你将学习在两个实体间,配置一对零或者一对多的关系。
我们使用student和studentaddress实体来配置这种关系:
public class student { public int studentid { get; set; } public string studentname { get; set; } public virtual studentaddress address { get; set; } } public class studentaddress { public int studentaddressid { get; set; } public string address1 { get; set; } public string address2 { get; set; } public string city { get; set; } public int zipcode { get; set; } public string state { get; set; } public string country { get; set; } public virtual student student { get; set; } }
你可以看这篇文章,entity relationship 来理解ef怎么管理一对一、一对多、多对多关系的。
一对零或一对一的关系发生在这样的两个实体之间:当一个表的主键,是另外一个表的主键并且是外键的时候,所以我们需要配置student实体中的studentid属性为主键,然后studentaddressid既是主键又是外键。
使用数据注解配置一对零或一对一关系
这里,我们将使用数据注解特性来给student实体和studentaddress实体,配置一对零或者一对一关系。
student实体遵循默认的约定,它包含一个studentid属性,所以到时候这个属性就会成为students表的主键,student实体我们不用作任何修改,就让它根据默认配置就行。
对于studentaddress实体,我们需要配置studentaddressid为主键和外键,因为studentaddressid遵循约定,所以只用给它配置外键。
public class student { public int studentid { get; set; } public string studentname { get; set; } public virtual studentaddress address { get; set; } } public class studentaddress { [foreignkey("student")] public int studentaddressid { get; set; } public string address1 { get; set; } public string address2 { get; set; } public string city { get; set; } public int zipcode { get; set; } public string state { get; set; } public string country { get; set; } public virtual student student { get; set; } }
这样就使用数据注解配置了一对零或一对一的关系了。
请注意:student包含studentaddress导航属性,并且studentaddress实体包含student导航属性。在一对零或一对一关系中,student可以在没有studentaddress的情况下被保存,但是studentaddress没有student的情况下不能保存。ef将会抛出异常,如果你没有student实体就保存studentaddress实体的话。
使用fluent api配置一对零或者一对一关系
这里我们将使用fluent api配置一对零或者一对一关系。
protected override void onmodelcreating(dbmodelbuilder modelbuilder) { // configure student & studentaddress entity modelbuilder.entity<student>() .hasoptional(s => s.address) // mark address property optional in student entity .withrequired(ad => ad.student); // mark student property as required in studentaddress entity. cannot save studentaddress without student }
上面的例子中,我们从student实体开始配置,hasoptional()方法配置student实体中的address导航属性为可选的【保存student实体的时候,可以没有studentaddress实体】,然后withrequired方法设置studentaddress实体中的student导航属性为必须的【保存studentaddress实体的时候,必须要有student】。上面的代码,同样会使studentaddressid成为外键。
这样你就配置了一对零或者一对一的关系,这里student可以在没有studentaddress的情况下保存,但是studentaddress不能在没有student的情况下保存。ef api将会创建下面的数据库:
使用fluent api配置一对一的关系
我们可以使用fluent api配置一对一的关系,这样情况下,两个实体对于彼此都是必须的,意味着:student必须包含studentaddress,并且studentaddress必须包含student。
请注意:sql server中,一对一的关系,在技术上是不可能的。上面的代码设置将会永远是一对零或一对一关系。ef只是对实体形成一对一的关系,并不是在数据库中是一对一关系。
protected override void onmodelcreating(dbmodelbuilder modelbuilder) { // configure studentid as fk for studentaddress modelbuilder.entity<student>() .hasrequired(s => s.address) .withrequiredprincipal(ad => ad.student); }
上面的代码中,modelbuilder.entity<student>().hasrequired(s => s.address)
,是设置student实体中的 studentaddress导航类型的address属性是必须的,.withrequiredprincipal(ad => ad.student)
是设置studentaddress实体中的student属性是必须的。
使用 ef power tools为上面的一对一的例子创建实体对象模型,如下:
这一节,一对一的关系就讲解完了,下一节学习一对多的关系。
上一篇: 网站优化之谈网页的HTML静态化
下一篇: 2019最新微信养号攻略