Entity Framework Code First 中的一对零/一对关系






4.36/5 (12投票s)
在这里,我们将了解如何在 Entity Framework Code First 中配置两个实体之间的一对零/一对关系
引言
使用 entity framework code first 很有趣。但上周,我在配置实体之间的一对零或一对关系时遇到了一些问题,尤其是在使用诸如 HasOptional
与 WithRequired
、WithOptionalPrincipal
、WithOptionalDependent
等关键字的组合时。
因此,让我们看看如何使用这些关键字的组合来建立表之间的关系。以及针对不同的组合,哪些不同的结构化表被填充。
背景
假设我们有两个实体,Student
和 StudentContact
,其中
Student
可能只有一个联系人 (StudentContact
) 或没有- 但每个联系人 (
StudentContact
) 必须有一个Student
public class Student
{
public long Id { get; set; }
public string Name { get; set; }
/*May have a contact or not*/
public virtual StudentContact Contact { get; set; }
}
public class StudentContact
{
public long Id { get; set; }
public string ContactNumber { get; set; }
/*Must have a Student*/
public virtual Student Student { get; set; }
}
选项 1:HasOptional 然后 WithRequired
配置关系:从 Student
配置
Student
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasOptional(x => x.Contact)
.WithRequired(l => l.Student);
StudentContact
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasColumnName("Student_Id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Student
:
Id
是主键,带有自动递增
StudentContact
:
Id
(Student_Id
,因为我们进行了自定义) 既是主键又是来自Student
的Id
列的外键
选项 2:HasOptional 然后 WithOptionalPrincipal
配置关系:从 Student
配置
Student
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasOptional(x => x.Contact)
.WithOptionalPrincipal(l => l.Student);
StudentContact
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Student
:
Id
是主键,带有自动递增
StudentContact
:
Id
是主键,带有自动递增Student_Id
自动创建,并且在StudentContact
/Student
实体中没有导航属性Student_Id
不可为null
,并且是来自Student
的Id
列的外键
选项 3:HasOptional 然后 WithOptionalDependent
配置关系:从 Student
配置。
Student
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasOptional(x => x.Contact)
.WithOptionalDependent(l => l.Student);
StudentContact
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Student
:
Id
是主键,带有自动递增Contact_Id
自动创建,并且在StudentContact
/Student
实体中没有导航属性Contact_Id
是来自StudentContact
的Id
列的可为null
的外键
StudentContact
:
Id
是主键,带有自动递增
好吧,一些书籍是这样描述的
选择 WithRequiredPrincipal
将使您正在配置的实体成为主要的实体,这意味着它包含关系的 primary key。
选择 WithRequiredDependent
将使您正在配置的实体成为从属实体,这意味着它将具有关系的外键。
有趣的事情!!!
到目前为止,我们已经从 Student
配置中配置了关系,但假设我们想从 Student Contact
配置中配置关系,那么我们可以做什么…!!!
选项1Mimic:HasRequired 然后 WithOptional
配置关系:从 StudentContact
配置。
StudentContact
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasColumnName("Student_Id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
HasRequired(x => x.Student)
.WithOptional(l => l.Contact);
Student
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
这将与 选项1
相同
选项2Mimic:HasRequired 然后 WithOptional
配置关系:从 StudentContact
配置。
StudentContact
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasRequired(x => x.Student)
.WithOptional(l => l.Contact)
.Map(x => x.MapKey("Student_Id"));
Student
配置
HasKey(x => x.Id);
Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
这将与 选项2
相同。
选项3Mimic:HasRequired 然后 WithOptional
无法从 StudentContact
配置中配置关系。
限制
- 是的,可能存在一些我尚未遇到的错误,或者可能造成一些道德干扰。所以,如果您发现任何错误,请告诉我。
- 还有一些问题,例如我避免使用的导航属性。
在附件中查找框架 4 项目的 Visual Studio 2010(可在 VS2013 中运行)解决方案。如果运行该项目,它将在本地计算机上创建一个具有 2 个表和数据的 "UMS
" 数据库。您可以使用 app.config 进行更改。