【问题标题】:Getting Entity Framework to eager load on Group By让实体框架急切加载 Group By
【发布时间】:2012-09-10 07:16:58
【问题描述】:

我知道更改查询的形状会导致 Entity Framework 忽略包含调用,但是当我执行 select many 和 group by 时,有没有办法让它加载子属性。在下面的示例中,我想通知在特定时间段内预订工作的所有员工。在 where 之后调用 .ToArray() 只会访问数据库一次,但我正在内存中执行 SelectMany 和 GroupBy。有没有办法让 SelectMany 和 GroupBy 在 SQL 服务器上发生,并且仍然包含 ServiceType 和 Ship 以及 Employee 详细信息?

我正在寻找一种方法来对数据库进行一次 SQL 调用,并最终得到一份在该时间段内有工作的员工列表以及他们被分配到的工作。

var employeeJobs = DataContext.Jobs.
    Include("ServiceType").
    Include("Ship").
    Include("JobEmployees.Employee").
    Where(j => j.Start >= now && j.Start <= finish).
    OrderBy(j => j.Start).
    ToArray().
    SelectMany(j => j.JobEmployees, (j, je) => new { 
        Job = j, 
        Employee = je.Employee 
    }).GroupBy(j => j.Employee);

【问题讨论】:

  • 我在内存中做 SelectMany 和 GroupBy。你怎么知道? EF 中的查询形式可能难以捉摸。
  • 如果你想得到一个员工及其工作的列表,我建议你反过来查询:employeeJobs = from DataContext.Employees e where e.Any(...有工作标准...) 选择 e。如果没有智能感知帮助,我无法为您编写 LINQ 查询,但您明白了吗?
  • @GertArnold 对ToArray 的调用实现了结果,SelectManyGroupBy 在调用ToArray 之后 出现。
  • 如果我在 SelectMany 之前删除 ToArray() ,那么我会丢失 Includes 因此我的问题的重点。当我对结果执行 foreach 循环时,我得到一个异常,即数据读取器已经为命令打开,因为未加载子属性。我不想打开多个阅读器,因为它会延迟加载子属性并在每次迭代时访问数据库。我宁愿在内存中执行 SelectMany 和 GroupBy,也不愿多次访问数据库。
  • 关于同一主题的更多结论性讨论在这里:stackoverflow.com/questions/5343536/…

标签: c# linq entity-framework group-by ef-code-first


【解决方案1】:

以下应该有效:

var q = from e in DataContext.Employees
  where e.Job.Start > ....
  order by e.Job.Start
  select new {Employee = e, Job = e.Job, Ship = e.Job.Ship, ServiceType = e.Job.ServiceType}; // No db hit yet.

var l = q.GroupBy(item=>item.Employee) // no db hit yet.
    .ToList(); // This one causes a db hit.

【讨论】:

    【解决方案2】:

    为什么不创建一个视图然后从 EF 引用它? ,这还有一个额外的好处是数据库服务器而不是应用服务器来完成工作。

    【讨论】:

    • EF 的全部意义在于正在在数据库服务器上完成工作。因此,您的回答毫无意义。
    【解决方案3】:

    尝试在 groupby 之后将 Include() 移动到最后。

    【讨论】:

    • Include 是在 ObjectQuery 上定义的,而不是为 GroupBy 的返回类型 IQueryable 定义的。不要认为这行得通:(
    猜你喜欢
    • 1970-01-01
    • 2011-04-09
    • 2018-03-29
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2021-10-21
    • 1970-01-01
    相关资源
    最近更新 更多