欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

11.翻译系列:在EF 6中配置一对零或者一对一的关系【EF 6 Code-First系列】

程序员文章站 2022-04-08 17:37:34
原文链接:https://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx 这里,你将学习在两个实体间,配置一对零或者一对多的关系。 我们使用Student和 ......

原文链接:

这里,你将学习在两个实体间,配置一对零或者一对多的关系。
我们使用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将会创建下面的数据库:
11.翻译系列:在EF 6中配置一对零或者一对一的关系【EF 6 Code-First系列】

使用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为上面的一对一的例子创建实体对象模型,如下:
11.翻译系列:在EF 6中配置一对零或者一对一的关系【EF 6 Code-First系列】

这一节,一对一的关系就讲解完了,下一节学习一对多的关系。