当选择带有“include”的实体时,我的所有项都会被一个SQL连接语句获取。但是当我用它的子项将它投影到其他形式时,不再执行连接,而是执行每行单独的查询以获取子项。我该如何防止这种情况?我的目标是减少提取的列数,并减少查询量
这个问题让我相信这应该有效:https://github.com/aspnet/EntityFramework/issues/599
//executes ONE query as expected
context.Parents.Include(p => p.Children).ToList();
//executes MULTIPLE queries
context.Parents.Include(p => p.Children).Select(p => new {
Id = p.Id,
Name = p.Name,
Children = p.Children.Select(c => new {
Id = c.Id,
Name = c.Name
})
}).ToList();
答案 0 :(得分:4)
您看到多个查询已发送到数据库,因为EF Core还不够智能,无法将投影中的导航转换为JOIN。以下是跟踪此功能的问题 - https://github.com/aspnet/EntityFramework/issues/4007。
其他人之前提到的BTW,Include仅在实体类型为结果的一部分时起作用(即它意味着"如果您最终创建实体类型的实例,则确保填充此导航属性&#34 ;)答案 1 :(得分:3)
你的问题在这里:
std::cout << "max element: " << result->first.getFileSize() << "\t" << result->first.getFileName();
渴望加载语句Children = p.Children.Select(c => new {
Id = c.Id,
Name = c.Name
})
仅适用于没有投影的请求。
而不是你可以这样做:
Include()
AsEnumerable()对EF说,它之后的所有代码都应该在对象上执行,不应该转移到sql请求。
答案 2 :(得分:2)
对于EFCore 2.0.0-preview2(目前不在nuget上),这部分修复了
https://github.com/aspnet/EntityFramework/commit/0075cb7c831bb3618bee4a84c9bfa86a499ddc6c
这部分由#8584解决 - 如果收集导航是 没有编写,我们重新使用包含创建2个查询的管道, 而不是N + 1。如果收集过滤,我们仍然使用 正在发布旧的重写和N + 1查询
我不确切知道composed on
在这里的含义,是否只是意味着Child
对象无法过滤(大多数情况下都可以接受),但我的猜测肯定是你的原始查询现在可以工作。