我在一个相对庞大而复杂的数据模型上使用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类的帮助,解决了 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();
编辑3 02/11/2013 :上述代码存在问题(编辑2)。如果路径中的最后一个实体是引用而不是集合,则代码不会失败,但不会加载: - (
编辑4 :现在,我不是使用反射,而是通过在T4模板的帮助下查看实体数据模型来生成代码。
答案 0 :(得分:1)
有时存储过程最好。编写一个返回多个结果集的存储过程,每个结果集对应一个您希望急切加载的实体类型。与您尝试完成的操作相比,这是高度高性能,并且存储过程将比每个引用/集合的包含和单独的加载语句更具可读性。是的,EF将自动挂钩相关实体!
以下是针对EDMX和代码的多个结果集的sprocs的参考:
答案 1 :(得分:0)
尝试在多个上下文中分隔聚合。每个有界上下文都应该有一个单独的上下文。这样您就可以创建一个松散耦合的实体框架解决方案。
朱莉·勒曼(Julie Lerman)有一个很好的关于这个概念的视频。
答案 2 :(得分:0)
我更喜欢使用存储过程。易于维护,工作更快等。