11.翻譯系列:在EF 6中配置一對零或者一對一的關系【EF 6 Code-First系列】


原文鏈接:https://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

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將會創建下面的數據庫:
enter description here

使用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為上面的一對一的例子創建實體對象模型,如下:
enter description here

這一節,一對一的關系就講解完了,下一節學習一對多的關系。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM