我在理解Entity Framework Code Firsts关系创建方面遇到了问题,因为我更习惯于传统方式 .
one-to-many 关系对我来说似乎很清楚:孩子们只需要一个foreignKey ID属性来指示他们属于哪个Parent .
public class Parent
{
public int Id { get; set; }
public virtual ICollection<Child> Childs { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
现在,我不太确定如何正确创建 many-to-many 关系 . 可能还需要一个额外的表 ParentChild
,所以不需要(外键)ID属性吗?
public class Parent
{
public int Id { get; set; }
public virtual ICollection<Child> Childs { get; set; }
}
public class Child
{
public int Id { get; set; }
public virtual ICollection<Parent> Parents { get; set; }
}
现在,对于 one-to-one 关系,我不知道 . public class Parent {public int Id {get;组; }
public int ChildID { get; set; }
public virtual Child child { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
是否需要外部ID属性,或者我可以在 Parent
类中使用 Child
属性,在 Child
类中使用 Parent
-type属性?当我省略外键ID属性时,是否允许使用 virtual
关键字?
2 回答
我建议你看看实体框架流畅的api . 使用流畅的api可以轻松实现一对一的关系 . Explanation source . 如需快速参考:
您可以在datacontext类中重写OnModelCreating .
使用Entity Framework,您甚至不必指定外键关系,因为它会从模型中推导出它并相应地创建表 . 您实际需要做的唯一关系类型是0..1或1到0..1或1 .
不要忘记对象模型比数据库模型更宽松 . 您可以将属性存储在对象中但不在表中 .
您必须以不同的方式思考,因为EF将在数据库级别为您完成工作,您将可以访问对象模型中定义的所有属性,甚至是集合属性 .
我一直用来完成它的规则如下:
如果关系的基数为0..1或1,则使用对另一个实体对象的引用作为您的属性 . 如果基数很多,请使用集合 .
以下是一些用例:
1到多(每个父母很多孩子):
数据库中的结果将是具有单个属性(Id)的表父和具有两个属性的表Child,自动生成的Id和外键属性名为Parent_Id(表名然后是下划线,然后是相关类的键属性) ) .
多对多:
数据库中的结果将是具有单个属性(Id)的Table ClassA,具有单个属性(Id)的表ClassB和具有两个属性的第三个表(多对多关系的关系表)(this两个表的Ids) .
EF将推断它为了完成工作所需要的东西,所以你不必具体那么具体 .
现在,对于唯一有问题的,1比1:
遵循我在开始时给出的规则,这就是我们要做的 . 但在这种情况下,EF无法知道关系的方向......一对一的方向是两个方向 . 我们必须让它知道使用注释的方向(对我而言,与Fluent API相比最简单的方法) .
ClassB中的注释[ForeignKey(“ClassA”)]告诉EF使用ClassB中的Id列作为ClassA中的外键 .
数据库中的结果将是具有2个属性(Id和ClassB_Id)的Table ClassA和具有单个属性(Id)的表ClassB .
您不必自己创建外部键属性,因为EF会为您执行此操作 .