EF5 ObjectContext:如何用context.T.Attach()替换IQueryable <T> .Include(Path)

Oli*_*ROT 14 c# reflection entity-framework

我在一个相对大而复杂的数据模型上使用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");
Run Code Online (Sandbox Code Playgroud)

它可以通过使用字符串数组并在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"));
Run Code Online (Sandbox Code Playgroud)

而不是一个大的查询,我们将有4个较小的查询命中数据库.当然,我仍然希望利用图形路径的功能作为字符串.

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

我对么 ?

编辑1:嗯,我有一个额外的约束,也就是说,我正在使用自我追踪实体(STE).这意味着相关对象未实现为EntityCollection或EntityReference.所以Attach()和CreateSourceQuery()不可用!

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

编辑2:由于DbContext类的帮助,EDIT 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();
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*rco 0

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

Julie Lerman 有一个关于这个概念的复数视觉的精彩视频。