特别是标题为“在显式加载相关实体时应用过滤器”的部分。
我需要做类似的事情:
db.Configuration.LazyLoadingEnabled = false;
var class = db.Classes.Find(1);
db.Entry(class).Collection(c => c.Students).Query().Where(s => s.grade > 2.0).Load();
当我单步执行此操作并观察SQL事件探查器时,我会看到加载该类的查询。然后我看到应该加载学生的查询,但是class.Students从不填充并保持为null。但是,如果我从SQL事件探查器复制学生查询并自行运行,则会返回相应的学生。似乎Entity Framework正在运行学生查询并获得正确的结果,但是没有将它们附加到类对象。
我有办法解决这个问题,但我想知道我是否错过了一个步骤,或者我是否正在使用.Load()。
答案 0 :(得分:2)
如果Class
和Student
之间的关系是多对多关系,那么您所看到的行为就是预期的(虽然令人困惑,但我承认)。首先,如果您阅读了Intellisense关于Load
方法的内容......
枚举查询,以便查询服务器查询 System.Data.Entity.DbSet, System.Data.Objects.ObjectSet, System.Data.Objects.ObjectQuery,以及其他结果 查询将被加载到关联的System.Data.Entity.DbContext中, System.Data.Objects.ObjectContext或客户端上的其他缓存。这个 相当于调用ToList然后丢弃列表 没有实际创建列表的开销。
...它没有说明运行查询的实体的导航集合已填充,只是结果被加载到上下文中。
当您调用Load
时填充一对多关系时导航集合实际上不是此方法的结果,而是后续处理上下文称为关系范围或修复,这种处理不会发生多对多关系。
在这个问答中有更多细节:EF 4.1 loading filtered child collections not working for many-to-many
典型的是 - 对于多对多关系 - 您必须使用ToList()
而不是Load()
直接填充导航集:
var class1 = db.Classes.Find(1);
class1.Students = db.Entry(class1).Collection(c => c.Students).Query()
.Where(s => s.grade > 2.0).ToList();
这会将学生加载到上下文并同时填充class1
中的导航集。