首页 > 代码库 > EF Code-First 学习之旅 配置一对一的关系

EF Code-First 学习之旅 配置一对一的关系

1对1、1对0 的关系

例如:Entity1与零个或一个Entity2的实例有关系

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; }
}

 

在关系型数据库(如SQL Server)中,1对0或1的关系是一个表的主键将是另一个关系表的主键或外键

因此,创建Student表的时候设置StudentId为主键,StudentAddress表的StudentAddressId既是主键有事外键

在Code First默认约定中,StudentId属性默认为Student的主键,StudentAddressId默认为StudentAddress的主键,因此,我们只需要配置StudentAddressId又为外键就行

通过如下配置即可

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; }
}
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; }
}

 

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

}

 

上面的配置说明:StudentAddress在Student中的导航属性是可选的(没有StudentAddress也可以保存Student),Student在StudentAddress中的导航属性是必须的(没有Student的话StudentAddress保存不了),StudentAddressId作为外键

 

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; }
}

 

 

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.StudentId); 

}

 

 

一对一的关系

一对一在MS SQL Server中在技术上是不可能的,它总是1对0或1的关系,EF是在实体上表现为一对一的关系,而不是在数据库中

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)表明Address属性是必须的

.WithRequiredPrincipal(ad => ad.Student)

注:主实体是Student,依赖实体是StudentAddress

 

技术分享

 

 技术分享

 

EF Code-First 学习之旅 配置一对一的关系