【发布时间】:2017-08-18 14:30:34
【问题描述】:
我是 Entity Framework 代码优先的新手。这是我在 ASP.NET MVC 中的学习,使用代码优先创建数据库。
我有两个班级:
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public int Standard { get; set; }
public int SubjectId { get; set; }
[ForeignKey("SubjectId")]
public ICollection<Subject> Subjects { get; set; }
}
public class Subject
{
[Key]
public int SubjectId{ get; set; }
public string SubjectName { get; set; }
}
我正在尝试将Student 记录插入到Student 表中,该表具有引用Subject 表的外键SubjectId。
我正在尝试两种可能的方式:
第一种方法
using(var cxt = new SchoolContext())
{
Subject sub = new Subject() { SubjectId = 202, SubjectName ="Geology" };
Student stu = new Student() { Name = "Riya", SubjectId = 202 };
cxt.Subjects.Add(sub);
cxt.Students.Add(stu);
cxt.SaveChanges();
}
在这里,我创建了一个新的Subject 实例,其中包含SubjectId=202。现在,当我创建 Student 对象并将值 202 分配给 SubjectId 时,Insert 语句冲突。虽然有Subject 和SubjectId = 202,但是为什么会出现插入冲突呢?当我调试时,我看到导航属性Subjects 在这里为空。我不明白这里的意思。
第二种方法:
using( var cxt=new SchoolContext())
{
Student stu = new Student() { Name = "Riya" };
Subject sub = new Subject() { SubjectId = 202, SubjectName = "Geology" };
stu.Subjects.Add(sub);
cxt.Students.Add(stu);
cxt.SaveChanges();
}
但我得到一个空引用异常
对象引用未设置为对象的实例
为什么stu.Subjects 在这里为空?
所以我的问题是:
Student类中的SubjectId是什么意思? IE。它的价值与什么有关?我们可以显式设置它吗,如果可以,它会引用Subject表的主键吗?如果不是,是否仅出于 EF 代码约定目的而指定?类似地:导航属性的作用是什么?为什么为空,什么时候不为空?
我对导航属性的基本理解是,它是用来让EF判断两个实体之间的关系的。
任何人都可以通过示例澄清一下,将不胜感激。
【问题讨论】:
-
Student 类中不应有 SubjectId。你可能在找many-to-many:一个学生可以有很多科目,一个科目可以有很多学生。
-
在
Student中,确保将您的Subjects收藏标记为虚拟。 -
@Tipx - 只有在需要lazy loading 时才需要虚拟。这不是问题。
-
首先你需要决定你需要什么样的关系,其次你需要初始化外键对象以便能够通过外键插入
-
查看学生/课程示例here
标签: c# entity-framework ef-code-first-mapping