3

我一直在关注这篇文章,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 从未填充并保持为空。但是,如果我从 SQL 分析器复制学生查询并自己运行,则会返回相应的学生。似乎实体框架正在运行学生查询并返回正确的结果,但没有将它们附加到类对象。

有一些方法可以解决这个问题,但我想知道我是否错过了一步,或者我是否没有正确使用 .Load() 。

4

1 回答 1

2

Class如果和之间的关系Student多对多关系,那么您所看到的行为是预期的(尽管令人困惑,我承认)。首先,如果您阅读 Intellisense 关于该Load方法的说明...

枚举查询,以便对于服务器查询(例如 System.Data.Entity.DbSet、System.Data.Objects.ObjectSet、System.Data.Objects.ObjectQuery 等),查询结果将加载到关联的系统中.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

于 2012-07-24T00:10:33.160 回答