EntityFramework Code-First 簡易教程(八)-------一對一

配置一對一(One-to-One)關係:

兩個實體中,若是一個實體的一個實例與另外一個實體相關,則咱們就叫作一對一關係數據庫

查看以下代碼:ide

public class Student
{
    public 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; }
}

 

這裏,Student類只能擁有零個或最多一個StudentAddress類,因此符合一對一關係ui

在SQL Server數據庫中,一對一關係發生在當一張表的主鍵是另外一張表的主鍵或外鍵時,因此如上代碼中,咱們要配置StudentId爲主鍵,StudentAddressId既爲主鍵也爲外鍵。spa

1.使用DataAnnotations配置一對零或一對一關係:

Student類會根據Code-First默認約定將StudentId屬性配置爲主鍵,因此這裏咱們就不用額外的配置它了。.net

StudentAddress類中,咱們須要配置StudentAddressId既爲主鍵又爲外鍵,一樣的,Code-First默認約定會將StudentAddressId配置爲主鍵,因此這裏咱們僅僅須要使用[ForeignKey("Student")]特性將StudentAddressId屬性配置爲外鍵便可。翻譯

代碼以下:code

public class Student
{
    public 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; }
}
View Code

 

這樣,Student類和StudentAddress類就配置好了一對一關係。blog

若是StudentAddressId名稱改變了,好比下面代碼,改爲了StudentId,默認就不會建立主鍵了,須要手動添加上[Key]特性:ip

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}
     
public class StudentAddress 
{
    [Key, ForeignKey("Student")]
    public int StudentId { 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; }
}
View Code

這樣,StudentAddress類中的StudentId就被配置爲既是主鍵,又是外鍵。ci

注意: 雖然Student類中包含StudentAddress類屬性,StudentAddress類中也包含Student類屬性,但Student類的StudentAddress類屬性能夠爲空,而StudentAddress類的Student類屬性不能爲空!若是保存一個Student類屬性爲空的StudentAddress類,會拋出異常。

 

 

2.使用Fluent API配置一對零或一對一關係:

下面咱們將不使用任何DataAnnotations特性(雖然它們能夠一塊兒使用)僅僅使用Fluent API來配置一對一關係。

當Student類的命名和StudentAddress類的命名遵循默認約定的時候:

既然默認約定會自動爲Student和StudentAddress建立主鍵,因此這裏咱們僅僅須要把StudentAddressId配置爲外鍵

代碼以下:

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實體的Address屬性使用了HasOptional()方法,即Address屬性不是必須的,可爲空,又爲StudentAddress類的Student屬性使用了WithRequired()方法,即Student屬性爲必填,不能爲空,若是存儲StudentAddress實體的時候發現Student屬性爲空,則會拋出異常。

這樣配置之後,StudentAddressId就已是外鍵了。

當StudentAddress類的命名不遵循默認約定的時候:

以下代碼,咱們想要StudentAddress類的StudentId屬性成爲主外鍵

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}
     
public class StudentAddress 
{
    public int StudentId { 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; }
}

 

Fluent API配置以下:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure StudentId as PK for StudentAddress
    modelBuilder.Entity<StudentAddress>()
        .HasKey(e => e.StudentId);
        
    // Configure StudentId as FK for StudentAddress
    modelBuilder.Entity<Student>()
                .HasOptional(s => s.Address) 
                .WithRequired(ad => ad.Student); 

}

 

 

3.使用Fluent API配置一對一關係:

說白了,所謂的一對一關係,便是兩個實體類中做爲主外鍵的類屬性都不能爲空。

注意:一對一關係在SQL Server中並非必須,一般使用一對零或一對一。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure StudentId as PK for StudentAddress
    modelBuilder.Entity<StudentAddress>()
        .HasKey(e => e.StudentId);
        
    // 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類的Address屬性爲必須,WithRequiredPrincipal(ad => ad.Student) 方法使的StudentAddress類的Student屬性爲必須。

注意:這裏主要的實體類是Student,依賴的實體類是StudentAddress。

DataAnnotations and Fluent API都會建立以下的一對零或一對一關係的數據庫:

one-to-one relationship in code first

咱們能夠檢查Student表和StudentAddress表之間的關係:

one-to-one relationship in code first

圖表關係以下

one-to-one relationship in code first

 

 

 

 

 啊啊啊啊啊,雖然最近忙成狗,可是說好的翻譯,必定會堅持下去的!!!

相關文章
相關標籤/搜索