EF 6 Code-First系列文章目錄:
- 1 翻譯系列:什么是Code First(EF 6 Code First 系列)
- 2.翻譯系列:為EF Code-First設置開發環境(EF 6 Code-First系列)
- 3.翻譯系列:EF Code-First 示例(EF 6 Code-First系列)
- 4.翻譯系列:EF 6 Code-First默認約定(EF 6 Code-First系列)
- 5.翻譯系列:EF 6中數據庫的初始化(EF 6 Code-First 系列)
- 6.翻譯系列:EF 6 Code-First中數據庫初始化策略(EF 6 Code-First系列
- 7.翻譯系列:EF 6中的繼承策略(EF 6 Code-First 系列)
- 8.翻譯系列: EF 6中配置領域類(EF 6 Code-First 系列)
- 9.翻譯系列:EF 6以及EF Core中的數據注解特性(EF 6 Code-First系列)
- 9.1 翻譯系列:數據注解特性之----Table【EF 6 Code-First 系列】
- 9.2 翻譯系列:數據注解特性之---Column【EF 6 Code First系列】
- 9.3 翻譯系列:數據注解特性之Key【EF 6 Code-First 系列】
- 9.4 翻譯系列:EF 6以及 EF Core中的NotMapped特性(EF 6 Code-First系列)
- 9.5 翻譯系列:數據注解之ForeignKey特性【EF 6 Code-First系列】
- 9.6 翻譯系列:數據注解之Index特性【EF 6 Code-First系列】
- 9.7 翻譯系列:EF數據注解特性之--InverseProperty【EF 6 Code-First系列】
- 9.8 翻譯系列:數據注解特性之--Required 【EF 6 Code-First系列】
- 9.9 翻譯系列:數據注解特性之--MaxLength 【EF 6 Code-First系列】
- 9.10 翻譯系列:EF數據注解特性之StringLength【EF 6 Code-First系列】
- 9.11 翻譯系列:數據注解特性之--Timestamp【EF 6 Code-First系列】
- 9.12 翻譯系列:數據注解特性之ConcurrencyCheck【EF 6 Code-First系列】
- 10.翻譯系列:EF 6中的Fluent API配置【EF 6 Code-First系列】
- 10.1.翻譯系列:EF 6中的實體映射【EF 6 Code-First系列】
- 10.2.翻譯系列:使用Fluent API進行屬性映射【EF 6 Code-First】
- 11.翻譯系列:在EF 6中配置一對零或者一對一的關系【EF 6 Code-First系列】
- 12.翻譯系列:EF 6 中配置一對多的關系【EF 6 Code-First系列】
- 13.翻譯系列:Code-First方式配置多對多關系【EF 6 Code-First系列】
- 14.翻譯系列:從已經存在的數據庫中生成上下文類和實體類【EF 6 Code-First系列】
- 15.翻譯系列:EF 6中的級聯刪除【EF 6 Code-First 系列】
- 16.翻譯系列:EF 6 Code -First中使用存儲過程【EF 6 Code-First系列】
- 17.翻譯系列:將Fluent API的配置遷移到單獨的類中【EF 6 Code-First系列】
- 18.翻譯系列:EF 6 Code-First 中的Seed Data(種子數據或原始測試數據)【EF 6 Code-First系列】
- 19.翻譯系列:EF 6中定義自定義的約定【EF 6 Code-First約定】
- 20.翻譯系列:Code-First中的數據庫遷移技術【EF 6 Code-First系列】
- 20.1翻譯系列:EF 6中自動數據遷移技術【EF 6 Code-First系列】
- 20.2.翻譯系列:EF 6中基於代碼的數據庫遷移技術【EF 6 Code-First系列】
- 21.翻譯系列:Entity Framework 6 Power Tools【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為上面的一對一的例子創建實體對象模型,如下:
這一節,一對一的關系就講解完了,下一節學習一對多的關系。