问题描述
我正在尝试使用 Entity Framework 6 编写关系数据库应用程序.我的类类似于:
I'm trying to write a relational database application using Entity Framework 6. I have classes analogous to:
public class Subject
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
public class Student
{
public int ID { get; set; }
public int SubjectID { get; set; }
public string Name { get; set; }
public virtual Subject Subject { get; set; }
}
(好吧,这是一个不好的例子,因为实际上你希望每个学生都学习不止一门学科,但我们暂时忽略这个,因为这是我能想到的最好的例子.)
(OK this is a bad example because in reality you'd want each student to be in more than one subject but let's ignore this for now as it was the best example that I could think of.)
问题在于,只要有一个没有学生的科目,subjectInstance.Students
不会返回一个空集合,而是返回 null
.这意味着我不能调用 subjectInstance.Students.Add(studentInstance)
来添加第一个学生.我必须单独添加学生,方法是在手动设置 studentInstance
上的 SubjectID
字段后调用 contextInstance.Students.Add(studentInstance)
.一旦已有一名或多名学生与该科目相关联,subjectInstance.Students
不再为空,我可以按预期方式添加更多学生.
The problem is that, whenever there's a subject with no students, instead of subjectInstance.Students
returning an empty collection it instead returns null
. This means that I cannot call subjectInstance.Students.Add(studentInstance)
to add the first student. I instead have to add the student separately, by calling contextInstance.Students.Add(studentInstance)
after manually setting the SubjectID
field on studentInstance
. Once there's one or more students already associated with the subject, subjectInstance.Students
is no longer null and I can add further students in the expected way.
我已经尝试过的:
从
public virtual ICollection<Student> 中删除
- 没有变化virtual
学生{得到;放;}
Removing
virtual
frompublic virtual ICollection<Student> Students { get; set; }
- no change
在尝试访问集合之前调用 contextInstance.Entry(subjectInstance).Collection("Students").Load()
- 有效,但它很混乱并且破坏了关注点的分离(模块处理数据的人不必担心加载数据)
Calling contextInstance.Entry(subjectInstance).Collection("Students").Load()
before attempting to access the collection - works but it's messy and breaks separation of concerns (the modules that work with the data shouldn't have to concern themselves with loading the data)
在创建 subjectInstance
之前的某个时间点调用 contextInstance.Subjects.Include("Students")
- 没有变化
Calling contextInstance.Subjects.Include("Students")
at some point before creating subjectInstance
- no change
推荐答案
作为 官方文档 演示,如果你想防止 Null 引用异常,你应该始终在实体构造函数中初始化你的集合导航属性.
As the official documentation demonstrates, you should always initialize your collection navigation properties inside the entity constructor if you want to prevent a Null reference exception.
public Subject()
{
Students = new HashSet<Student>(); // you may also use List<Student>, but HashSet will guarantee that you are not adding the same Student mistakenly twice
}
仅当至少有一个学生时,实体框架才会填充 Students
属性(使用代理),否则它将保持该属性不变(如果您尚未初始化它,则为 null).
Entity framework will fill Students
property (using a proxy) only if there is at least a student, else it will leave the property as is (null if you have not initialized it).
当实体不是代理时,Entity Framework 仅在对上下文调用 SaveChanges()
时跟踪其更改,并使用其原始 entity 状态进行比较.这个答案将进一步阐明这种行为.
When the entity is not a proxy, then Entity Framework tracks its changes only when calling SaveChanges()
on the context, using its original entity state for comparison. This answer will further clarify this behavior.
这篇关于Entity Framework 6 导航集合为空而不是空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!