我在理解Entity Framework Code Firsts关系创建方面遇到了问题,因为我更习惯于传统方式。
一对多关系对我来说似乎很清楚:孩子们只需要一个foreignKey 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 int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
现在,我不太确定如何正确创建多对多关系。可能还需要一个额外的表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; }
}
现在,对于一对一关系,我不知道。 公共课家长 { 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属性,或者我可以在Child
类中拥有Parent
属性,在Parent
类中拥有Child
- 类型属性?当我省略外键ID属性时,是否允许virtual
关键字?
答案 0 :(得分:0)
我建议你看看实体框架流畅的api。使用流畅的api可以轻松实现一对一的关系。 Explanation source。如需快速参考:
public class Student
{
public Student() { }
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
[Required]
public virtual StudentAddress StudentAddress { 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; }
}
您可以在datacontext类中覆盖OnModelCreating。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<StudentAddress>()
.HasKey(e => e.StudentId);
modelBuilder.Entity<StudentAddress>()
.Property(e => e.StudentId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<StudentAddress>()
.HasRequired(e => e.Student)
.WithRequiredDependent(s => s.StudentAddress);
base.OnModelCreating(modelBuilder);
}
答案 1 :(得分:0)
使用Entity Framework,您甚至不必指定外键关系,因为它会从模型中推断出它并相应地创建表。您实际需要做的唯一关系类型是0..1或1到0..1或1。
不要忘记对象模型比数据库模型更宽松。您可以将属性存储在对象中但不在表中。
您必须以不同的方式思考,因为EF将在数据库级别为您完成工作,您将可以访问对象模型中定义的所有属性,甚至是集合属性。
我一直用来完成它的规则如下:
如果关系的基数为0..1或1,则使用对其他实体对象的引用作为您的属性。如果基数很多,请使用集合。
以下是一些用例:
1对多(每位父母很多孩子):
public class Parent
{
public int Id { get; set; }
// Navigation property
public virtual ICollection<Child> Childs { get; set; }
}
public class Child
{
public int Id { get; set; }
// Navigation property
public virtual Parent Parent { get; set; }
}
数据库中的结果将是具有单个属性的表父(Id)和具有两个属性的表Child,自动生成的Id和外键属性名为Parent_Id(表名然后是下划线,然后是关键属性相关课程。)
多对多:
public class ClassA
{
public int Id { get; set; }
// Navigation property
public virtual ICollection<ClassB> ClassBs { get; set; }
}
public class ClassB
{
public int Id { get; set; }
// Navigation property
public virtual ICollection<ClassA> ClassAs { get; set; }
}
数据库中的结果将是具有单个属性(Id)的Table ClassA,具有单个属性(Id)的表ClassB和具有两个属性(Id)的第三个表(多对多关系的关系表)属性(这两个表的ID)。
EF将推断出为了完成这项工作所需要的东西,所以你不必具体那么具体。
现在是唯一有问题的,1比1:
public class ClassA
{
public int Id { get; set; }
// Navigation property
public virtual ClassB ClassB { get; set; }
}
public class ClassB
{
public int Id { get; set; }
// Navigation property
public virtual ClassA ClassA { get; set; }
}
按照我在开头给出的规则,这就是我们要做的。但在这种情况下,EF无法知道关系的方向......一对一的方向是两个方向。我们必须让它知道使用注释的方向(对我而言,与Fluent API相比最简单的方法)。
public class ClassA
{
public int Id { get; set; }
// Navigation property
public virtual ClassB ClassB { get; set; }
}
public class ClassB
{
[ForeignKey("ClassA")]
public int Id { get; set; }
// Navigation property
public virtual ClassA ClassA { get; set; }
}
ClassB中的注释[ForeignKey(&#34; ClassA&#34;)]告诉EF使用ClassB中的Id列作为ClassA中的外键。
数据库中的结果将是具有2个属性(Id和ClassB_Id)的Table ClassA和具有单个属性(Id)的表ClassB。
您不必自己创建外部关键属性,因为EF会为您完成。