实体框架 - .Load()的麻烦

时间:2012-07-23 22:46:09

标签: entity-framework

我一直在关注这篇文章,http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

特别是标题为“在显式加载相关实体时应用过滤器”的部分。

我需要做类似的事情:

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()。

1 个答案:

答案 0 :(得分:2)

如果ClassStudent之间的关系是多对多关系,那么您所看到的行为就是预期的(虽然令人困惑,但我承认)。首先,如果您阅读了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中的导航集。