看来我无法从数据库中获取父级及其子级的子集。
例如...
db.Parents
.Include(p => p.Children)
.Where(p => p.Children.Any(c => c.Age >= 5))
这将返回所有有 5 岁以上孩子的“父母”,但如果我迭代“Parents.Children”集合,所有孩子都将出现(而不仅仅是 5 岁以上的孩子)。
现在这个查询对我来说确实有意义(我要求包含子项并且我已经得到了它们!),但可以想象我希望在某些情况下将 where 子句应用于子集合。
我怎样才能得到一个 IEnumerable,其中每个父母都有一个经过过滤的孩子集合(年龄>=5)?
在单个数据库往返中获取具有已过滤子集合的父集合的唯一方法是使用投影。不可能使用预加载(Include
)因为它不支持过滤,Include
始终加载整个集合。 @Daz 显示的显式加载方式需要每个父实体进行一次往返。
Example:
var result = db.Parents
.Select(p => new
{
Parent = p,
Children = p.Children.Where(c => c.Age >= 5)
})
.ToList();
您可以直接使用这个匿名类型对象的集合。 (您还可以投影到您自己的命名类型而不是匿名投影(但不能投影到像Parent
).)
EF 的上下文也将填充Children
的集合Parent
如果您不禁用更改跟踪(使用AsNoTracking()
例如)。在这种情况下,您可以将父项从匿名结果类型中投影出来(发生在内存中,没有数据库查询):
var parents = result.Select(a => a.Parent).ToList();
parents[i].Children
将包含每个过滤的子项Parent
.
Edit到问题中的最后一次编辑:
我正在寻找 a) 拥有 5 岁以上孩子的父母名单(以及
仅包括那些孩子)。
上面的代码将返回all父母,并且只包括孩子Age
>= 5,所以如果只有孩子,父母也可能有一个空的孩子集合Age
Where条款让父母只得到有的父母最后一个 (Any
)孩子与Age
>= 5:
var result = db.Parents
.Where(p => p.Children.Any(c => c.Age >= 5))
.Select(p => new
{
Parent = p,
Children = p.Children.Where(c => c.Age >= 5)
})
.ToList();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)