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列就可为空了。

 


 

 

最近太忙了,工做上,生活上,总之,好事多磨吧,既然下定决心了要更下去,就不能食言。今天就先到这里吧,下篇将讲多对多关系的操做。

相关文章
相关标签/搜索