【问题标题】:Selecting distinct rows but always select the last one选择不同的行,但始终选择最后一行
【发布时间】:2020-10-22 06:03:52
【问题描述】:

我想查询具有不同 RailcarNumber 列的 StorageDetails 表。在 RailcarNumber 重复的地方,我只想要最新的。

我尝试过这样的事情:

var details = DbContext.StorageDetails
    .Where(d => railcars.Contains(d.RailcarNumber))
    .OrderByDescending(d => d.Id)
    .GroupBy(d => d.RailcarNumber)
    .Select(g => new
    {
        RailcarNumber = g.Key,
        Details = g.First()
    })
    .ToList();

但它抱怨 First() 的引用。

LINQ 表达式 '(GroupByShaperExpression:
KeySelector: (s.RailcarNumber),
ElementSelector:(EntityShaperExpression:
实体类型:StorageDetail
值缓冲区表达式:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: 假
)
) .First()' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。

我不知道我还能怎么做我需要的。 Distinct() 似乎没有任何关于它选择哪一个的选项。

【问题讨论】:

  • 您使用的是哪种第一种方法?它看起来不像 LINQ First,因为它需要一个参数,那是自定义方法吗?
  • @SelmanGenç:对不起,这是尝试Take(1)时留下的。
  • 尝试在 GroupBy 之后添加 .AsEnumerable,查询的 Select 部分将在内存而不是 DB 中计算。
  • @JonathanWood 无法将其转换为 SQL。在分组后添加一个 As Enumerable 并从内存中提取投影
  • @Nkosi:调用AsEnumerable() 会删除所有匹配的行,这超出了我的需要。我知道 SQL Server 可以进行子查询。似乎应该有办法做到这一点。

标签: c# .net linq .net-core entity-framework-core


【解决方案1】:

对于 EF Core 3.1,您可以将查询从 OrderByDescending().First() 更改为 GroupBy().Max().Contains() 并获取单个 SQL 查询:

var sdIDs = DbContext.StorageDetails
              .Where(sd => railcars.Contains(sd.RailcarNumber))
              .GroupBy(sd => sd.RailcarNumber)
              .Select(sdg => sdg.Max(sd => sd.Id));

var details = DbContext.StorageDetails
                .Where(sd => sdIDs.Contains(sd.Id))
                .Select(sd => new {
                    sd.RailcarNumber,
                    Details = sd
                })
                .ToList();

【讨论】:

  • 可能是我能做的最好的了。谢谢。一个问题:这是两次访问数据库,对吗?在第二个查询中遇到第一个查询时是否执行?
  • @JonathanWood 那是每一行在第二个加上第二个的行程。
  • @Nkosi:我相信这将是两次旅行。实体框架似乎能够使用IN 处理Contains() 子句。是什么让你说这将是每一行的旅行?无论如何,我已经在两个查询中添加了ToList(),所以现在应该是两个查询。
  • @JonathanWood 我看到每个 ID 都调用了包含,但如果 EF 可以翻译,那么我会更正。试试看会发生什么。
  • @JonathanWood 在带有 EF 3.1 的 LINQPad 中,我看到一个查询,因为子查询 sdIDs 未实例化,因此 details 查询将其转换为 SQL 作为主查询的子查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
相关资源
最近更新 更多