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

一對多(One-to-Many)關係:

下面,咱們來介紹Code-First的一對多關係,好比,在一個Standard(年級)類中包含多個Student類。數據庫

若是想了解更多關於one-to-one,one-to-many,many-to-many關係的信息,請訪問Entity Relationshipide

 

1.使用DataAnnotations配置One-to-Many關係:

以下代碼所示:ui

public class Student
{
    public Student() { }

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

    public virtual Standard Standard { get; set; }
}
       
public class Standard
{
    public Standard()
    {
        Students = new List<Student>();
    }
    public int StandardId { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

如上代碼所示,Student實體類包含導航屬性Standard,並且Standard實體類包含集合屬性Student,這就是默認的一對多關係。spa

若是實體類遵循這種這種默認約定,也就是默認便是一對多關係了,咱們就不需藥額外的配置DataAnnotations或者Fluent API。.net

在數據庫中,Code-First會經過在Student表中加入Standard_StandardId外鍵列來建立一對多關係。code

one-to-one relationship in code first

咱們建議在一個實體類中包含外鍵屬性,如上代碼中,若是在Student實體類中建立StandardId屬性,它就會自動變成外鍵,由於它遵循了默認約定,即外鍵的格式應該爲<類型名稱>Id的格式。對象

一樣的,若是咱們建立的外鍵屬性名字沒有遵循默認的命名規定,那麼咱們就須要本身手動添加特性了,以下代碼所示,Student類包含了一個StandardRefId屬性:blog

public class Student
{
    public Student() { }

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

    public int StandardRefId { get; set; }
        
    [ForeignKey("StandardRefId")]
    public virtual Standard Standard { get; set; }
}
       
public class Standard
{
    public Standard()
    {
        StudentsList = new List<Student>();
    }
    public int StandardId { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

若是代碼,咱們必需要給Standard屬性加上[ForeignKey("StandardRefId")]特性,這樣建立數據庫的時候纔會將StandardRefId設置爲外鍵,數據庫以下:ip

Entity Framework code-first example

 

 

 

2.使用Fluent API配置One-to-Many關係:

仍是拿上面兩個類的例子ci

Student類和Standard類代碼以下:

public class Student
{
    public Student(){ }

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

    public int StandardId { get; set; }

    public virtual Standard Standard { get; set; }
}
       
public class Standard
{
    public Standard()
    {
        StudentsList = new List<Student>();
    }
    public int StandardId { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

 

使用Fluent API配置一對多關係代碼:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        //one-to-many 
        modelBuilder.Entity<Student>()
                    .HasRequired<Standard>(s => s.Standard) // Student entity requires Standard 
                    .WithMany(s => s.Students); // Standard entity includes many Students entities

}

這是默認兩個類的外鍵命名都遵循約定命名狀況的時候,若是Student類包含了一個不遵循約定命名的外鍵名稱呢,以下所示:

public class Student
{
    public Student(){ }

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

    //StdId有一個不一樣於Code-First默認約定命名的名稱
    public int StdId { get; set; }

    public virtual Standard Standard { get; set; }
}
       
public class Standard
{
    public Standard()
    {
        StudentsList = new List<Student>();
    }
    public int StandardId { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

如上所示,StdId就沒有遵循默認的<類型名稱>Id的外鍵命名約定,因此咱們的Fluent API配置以下:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        //one-to-many 
        modelBuilder.Entity<Student>()
                    .HasRequired<Standard>(s => s.Standard)
                    .WithMany(s => s.Students)
                    .HasForeignKey(s => s.StdId);

}

 

如你所見, modelBuilder.Entity<Student>().HasRequired<Standard>(s => s.Standard) 特別指定Student實體的Standard屬性不能爲空, .WithMany(s => s.Students).HasForeignKey(s => s.StdId) 指定了Standard實體包含多個Student實體,並且外鍵爲StdId。

注意:每個泛型方法都返回了一個該類型對象,因此纔能有這種一串打點的寫法^_^)

因此針對上面的配置代碼,咱們也能夠以Standard類開頭來寫配置代碼,以下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        //configure one-to-many
        modelBuilder.Entity<Standard>()
                    .HasMany<Student>(s => s.Students) //Standard has many Students
                    .WithRequired(s => s.Standard)  //Student require one Standard
                    .HasForeignKey(s => s.StdId);//Student includes specified foreignkey property name for Standard
}

 

代碼運行後將會建立以下的數據庫:

one-to-one relationship in code first

注意StdId是不爲空的列,因此每次加入和更新Students表的時候必需要指定Student實體類的Standard屬性。

在One-to-Many關係中配置可空外鍵:

很簡單,使用HasOptional方法代替HasRequired方法便可。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        //one-to-many 
        modelBuilder.Entity<Student>()
                    .HasOptional<Standard>(s => s.Standard)
                    .WithMany(s => s.Students)
                    .HasForeignKey(s => s.StdId);

}

 

 這樣,Students表的StdId列就可爲空了。

 


 

 

最近太忙了,工做上,生活上,總之,好事多磨吧,既然下定決心了要更下去,就不能食言。今天就先到這裏吧,下篇將講多對多關係的操做。

相關文章
相關標籤/搜索