Entity Framework 6 导航集合为空而不是空 [英] Entity Framework 6 navigation collections are null instead of empty

查看:11
本文介绍了Entity Framework 6 导航集合为空而不是空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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 from public 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 导航集合为空而不是空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆