EF7投影并不急于加载

时间:2016-02-10 13:45:20

标签: c# asp.net entity-framework

当选择带有“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();

3 个答案:

答案 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对象无法过滤(大多数情况下都可以接受),但我的猜测肯定是你的原始查询现在可以工作。