这篇文章您将学习如何使用Fluent API配置两个实体之间的一对一关系,如果它们不遵循EF Core约定。
通常,您不需要手动配置一对一关系,因为EF Core包含一对一关系约定。但是,如果键或外键属性不符合约定,则可以使用数据注释属性或Fluent API来配置两个实体之间的一对一关系。
让我们进行以下配置间的一种一对一关系Student
和StudentAddress
实体,不按外键惯例。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public StudentAddress Address { get; set; }
}
public class StudentAddress
{
public int StudentAddressId { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public int AddressOfStudentId { get; set; }
public Student Student { get; set; }
}
要配置在EF Core使用 Fluent API 一对一的关系,使用HasOne
,WithOne
和HasForeignKey
方法,如下所示。
public class SchoolContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=.\SQLEXPRESS;Database=EFCore-SchoolDB;Trusted_Connection=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasOne<StudentAddress>(s => s.Address)
.WithOne(ad => ad.Student)
.HasForeignKey<StudentAddress>(ad => ad.AddressOfStudentId);
}
public DbSet<Student> Students { get; set; }
public DbSet<StudentAddress> StudentAddresses { get; set; }
}
在上面的示例中,以下代码段配置了一对一关系。
modelBuilder.Entity<Student>()
.HasOne<StudentAddress>(s => s.Address)
.WithOne(ad => ad.Student)
.HasForeignKey<StudentAddress>(ad => ad.AddressOfStudentId);
让我们一步一步地理解它。
modelBuilder.Entity<Student>()
开始配置Student
实体。- 该
.HasOne<StudentAddress>(s => s.Address)
方法指定Student
实体StudentAddress
使用lambda表达式包含一个引用属性。 .WithOne(ad => ad.Student)
配置关系的另一端即StudentAddress
实体。它指定StudentAddress
实体包含Student
类型的引用导航属性。.HasForeignKey<StudentAddress>(ad => ad.AddressOfStudentId)
指定外键属性名称。
上面的示例将在数据库中创建以下表:
下图说明了一对一关系的Fluent API配置。
您可以使用StudentAddress
相同的方式开始配置实体,如下所示。
modelBuilder.Entity<StudentAddress>()
.HasOne<Student>(ad => ad.Student)
.WithOne(s => s.Address)
.HasForeignKey<StudentAddress>(ad => ad.StudId);
因此,您可以在EF Core 中配置一对一关系。