繁体   English   中英

EF Core LINQ GROUPBY 然后 Select 获取实体的多个属性

[英]EF Core LINQ GROUPBY Then Select to get more than one properties of the entity

我有 2 个表 Outlet 和 Order 具有以下模式:

Outlet          Order
------    -------------------
Id              Id
Name            Name
                OrderCompletedTime
                NextOrderDueTime
                OutletIds

早些时候,当我想使用实体框架核心为每个出口获取 NextOrderDueTime 时,我做了:

return _dbAccessor.RequestContext.MyDbContext.Order
                .Where(i => i.OutletId == _dbAccessor.RequestContext.OutletId &&
                            !i.IsRemoved && i.NextOrderDueTime.HasValue)
                .GroupBy(i => i.OutletId)
                .Select(g => new { OutletId = g.Key, NextOrderDueTime = g.Min(x => x.NextOrderDueTime) })
                .ToDictionary(i => i.OutletId, i => i.NextOrderDueTime);

现在在 UI 上,我们需要将此到期时间作为链接,并希望用户根据订单 ID 导航到该订单详细信息页面

如何更改上述查询以同时返回 OrderId 以及时间?

我的想法:

  1. 将方法的返回类型从Dictionary<int, DateTimeOffset?>更改为Dictionary<int, Tuple<int,DateTimeOffset?>>

  2. 我尝试将 Linq 查询更改为:

return _dbAccessor.RequestContext.MyDbContext.Order
                .Where(i => i.OutletId == _dbAccessor.RequestContext.OutletId &&
                            !i.IsRemoved && i.NextOrderDueTime.HasValue)
                .GroupBy(i => i.OutletId)
                   .Select(g =>
                       new
                       {
                           OutletId = g.Key,
                           NextOrderDueTime = g.FirstOrDefault(x => x.NextOrderDueTime == g.Min(y => y.NextOrderDueTime)).NextOrderDueTime,
                           NextOrderId = g.FirstOrDefault(x => x.NextOrderDueTime == g.Min(y => y.NextOrderDueTime)).OrderId
                       })
                       .ToDictionary(i => i.OutletId, i => new Tuple<int, DateTimeOffset?>(i.NextOrderId, i.NextOrderDueTime));

但这会在运行时引发异常?

请帮助让我知道我在这里做错了什么。

当您返回时,您可以将整个订单连同 outletid 一起拿走:

.Select(g => new { 
  OutletId = g.Key, 
  NextOrder = g.OrderBy(x => x.NextOrderDueTime).FirstOrDefault() 
})

您可以在此 select 从订单中获取多个属性:

.Select(g => new { 
  OutletId = g.Key, 
  NextOrder = g.OrderBy(x => x.NextOrderDueTime).FirstOrDefault() 
})
.Select(s => new {
  s.OutletId,
  NextOrderId = NextOrder.Id,
  NextOrder.NextOrderDueTime,
  NextOrderName = NextOrder.Name
})

ETC..

要欣赏的主要事情是,分组为您提供了一个具有密钥的 object,但它本身是具有该密钥的所有事物的列表,因此,如果您通过 DUeDat 之类的东西对列表进行排序并获取第一件事,那么您将拥有一个整个 object 具有最低的到期日,您可以从中获取各种东西

The.GroupBy(...).Select(...).ToDictionary(...); 自 EF Core 3.0 起无法转换为 SQL。

由于 EF Core 3.0 中的重大更改。 https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/break-changes ,EF Core 3.0 将抛出异常以确保您知道所有记录在 Order将在分组和 map 到字典之前从数据库中获取。

我能够让我的查询工作如下:

return _dbAccessor.RequestContext.MyDbContext.Order
                .Where(i => i.OutletId == _dbAccessor.RequestContext.OutletId &&
                            !i.IsRemoved && i.NextOrderDueTime.HasValue).AsEnumerable()
                .GroupBy(i => i.OutletId)
                   .Select(g =>
                       new
                       {
                           OutletId = g.Key,
                           NextOrderDueTime = g.FirstOrDefault(x => x.NextOrderDueTime == g.Min(y => y.NextOrderDueTime)).NextOrderDueTime,
                           NextOrderId = g.FirstOrDefault(x => x.NextOrderDueTime == g.Min(y => y.NextOrderDueTime)).OrderId
                       })
                       .ToDictionary(i => i.OutletId, i => new Tuple<int, DateTimeOffset?>(i.NextOrderId, i.NextOrderDueTime));

只需在 GroupBy 之前添加 AsEnumerable() 即可完成相同的操作,如另一个答案所示:

 _dbAccessor.RequestContext.MyDbContext.Order
                .Where(i => i.OutletId == _dbAccessor.RequestContext.OutletId &&
                            !i.IsRemoved && i.NextOrderDueTime.HasValue).AsEnumerable()
                .GroupBy(i => i.OutletId)
                  .Select(g => new { 
  OutletId = g.Key, 
  NextOrder = g.OrderBy(x => x.NextOrderDueTime).FirstOrDefault() 
})
.Select(s => new {
  s.OutletId,
  NextOrderId = NextOrder.Id,
  NextOrder.NextOrderDueTime,
  NextOrderName = NextOrder.Name
})`enter code here`;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM