我将Parent
和Child
个实体相互关联为1到M.我需要在单个SQL查询中与父项一起查询子项,但Include
方法不是在某些情况下正常工作。
这个对Parent
和Child
表进行了正确的单一查询(通过JOIN):
var r1 =
ctx.Set<Parent>()
.Include(p => p.Childs)
.Where(p => p.Id == 1)
.ToList();
一旦我动态创建一个匿名对象,孩子们就会迷路,而SQL只包含Parent的字段。检索孩子仍然很懒 - 他们仍然没有加载:
var r2 =
ctx.Set<Parent>()
.Include(p => p.Childs)
.Where(p => p.Id == 2)
.Select(p => new { myParent = p})
.ToList();
问题:
P.S。我想保持Parent虚拟的Childs属性。
答案 0 :(得分:4)
这是我所知道的所有EF版本的一般问题。 EF努力尽可能地传递'包含',但是当“查询的形状发生变化”时,'包含'会不可逆转地丢失。
例如,在以下情况下,查询的“形状”会发生变化:
可悲的是,我也不记得在MSDN上我偶然发现了“查询形状”的解释。如果我找到它,我会在这里放一个链接。
解决方案实际上非常简单:只是提前指定'include'部分,但最后结果。因此,开始时不要使用set.include(x)
,而是.Select( .. => new { .., x })
手动包含“x”。它也适用于分组,因为你也可以在那里进行投影。
然而,这不是解决方案。这是一个手动补丁/修补程序,它无法解决任何问题。考虑到您可能想要公开“IQueryable&lt;&gt;”通过某种界面,您可能希望公开一些“基础查询”。已包含一些内容。当然,这只是不可能以一般方式进行,就像界面的客户端进行投影或分组一样,他将失去包含,他甚至不知道哪些应该是。对我来说,这是EF的一个主要缺陷。
编辑:刚刚找到一个:.Include in following query does not include really不是MSDN,但同样好。
答案 1 :(得分:0)
在您创建匿名对象时,上下文的Parent
DbSet
Set<Parent>()
未填充任何数据,因此Child
ren也未被存储在上下文中。一种解决方案可能是将子项添加到匿名对象,但我不确定这会将它们添加到Set<Child>
DbSet
。
var r2 = ctx.Set<Parent>()
.Include(p => p.Childs)
.Where(p => p.Id == 2)
.Select(p => new { myParent = p, children = p.Childs })
.ToList();