14

我在一个相对大而复杂的数据模型上使用 Entity Framework 5 和 ObjectContext。我想解决链接多个 IQueryable.Include(Path) 以急切加载相关对象时生成的大查询。

例如,我正在做这样的事情:

var queryPe = context.Person.Where(p => p.Id == 110).Include(@"AA");
queryPe = queryPe.Include(@"BB.CC.DD");
queryPe = queryPe.Include(@"EE.FF");

它可以通过使用字符串数组并在运行时在 foreach 循环中链接每个图来使其通用。

相反,我想做这样的事情:

Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
pe.BB.Attach(pe.BB.CreateSourceQuery().Include(@"CC.DD"));
pe.EE.Attach(pe.EE.CreateSourceQuery().Include(@"FF"));

我们将有 4 个较小的查询访问数据库,而不是一个大查询。当然,我仍然想利用图形路径作为字符串的力量。

我可能错了,但这意味着我应该使用 relexion 按名称获取导航属性并在其上执行 CreateSourceQuery(),因为没有这样的扩展方法可以做到这一点。

我对么 ?

编辑 1:嗯,我有一个附加约束,也就是说,我正在使用自我跟踪实体 (STE)。这意味着相关对象没有具体化为 EntityCollection 或 EntityReference。所以 Attach() 和 CreateSourceQuery() 不可用!

所以我坚持使用 Context.LoadProperty 来处理对象图。只有可能吗?

编辑 2:在DbContext 类的帮助下,编辑 1中暴露的问题得到了解决。请参阅下面的代码:

Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
DbContext dbc = new DbContext(context, false);
dbc.Entry(pe).Collection(@"BB").Query().Include(@"CC.DD").Load();
dbc.Entry(pe).Reference(@"EE").Query().Include(@"FF").Load();

编辑 3 02/11/2013:上面提供的代码存在问题(编辑 2)。如果路径中的最后一个实体是引用而不是集合,则代码不会失败但不会加载:-(

编辑 4:现在我没有使用反射,而是在 T4 模板的帮助下通过查看实体数据模型来生成代码。

4

3 回答 3

1

有时存储过程是最好的。编写一个返回多个结果集的存储过程,每个结果集对应于您希望急切加载的每种类型的实体。与您要完成的任务相比,这是高性能的,并且存储过程将比每个引用/集合的包含和单独加载语句的混乱更具可读性。是的,EF 会自动连接相关实体!

以下是 EDMX 和代码优先的具有多个结果集的存储过程的参考:

http://msdn.microsoft.com/en-us/data/jj691402.aspx

于 2013-03-26T23:45:24.383 回答
0

尝试在多个上下文中分离您的聚合。每个有界上下文都应该有一个单独的上下文。通过这种方式,您可以创建松散耦合的实体框架解决方案。

Julie Lerman 有一个关于这个概念的复数视图的好视频。

于 2013-02-11T18:49:39.043 回答
0

我更喜欢使用存储过程。易于维护,工作速度更快等。

于 2013-04-02T19:49:35.837 回答