【问题标题】:How to select last record in a LINQ GroupBy clause如何在 LINQ GroupBy 子句中选择最后一条记录
【发布时间】:2016-07-11 10:30:28
【问题描述】:

我有以下带有 IDContactIdComment 的简单表格。

我想选择记录和GroupBy contactId。我用了这个LINQ扩展方法语句:

Mains.GroupBy(l => l.ContactID)
 .Select(g => g.FirstOrDefault())
 .ToList()

它返回记录14。如何使用LINQ 获得ContactID 最高的ID? (即返回36

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您可以订购商品

    Mains.GroupBy(l => l.ContactID)
    .Select(g=>g.OrderByDescending(c=>c.ID).FirstOrDefault()) 
    .ToList()
    

    【讨论】:

    • 尽管这个查询会返回正确的数据,但它会编译成 K+1 个 SQL 语句,其中 K 是键的数量(使用 LINQpad 来查看)。我今天遇到了同样的问题并以这种方式解决了它:` var lastCommentIDs = Mains.GroupBy(k => k.ContactID, e => e.ID, (k, e) => new { k, lastID = e.Max( x => x)}); var result = lastCommentIDs.Join(Mains, o => o.lastID, i => i.ID, (o, i) => new { ContactID = o.k, LastComment = i.Comment).ToList(); `
    • 嗨,@Dmitrij。感谢您的反馈。 Linqpad 正在使用 Linq to SQL,您是否尝试过使用 Linq to 实体?
    • 嗨,@tym32167。是的,我曾尝试跳入 EF,但不确定到底出了什么问题,但 EF 从 LINQ 语句中生成了最丑陋且绝对低效的 SQL 查询。可能我做错了什么,不确定但事实是:LINQ2SQL 比 EF 产生更多可预测的查询。 (至少我明白当我使用 LINQ2SQL 执行特定查询时会发生什么)
    【解决方案2】:

    在组中的项目上使用OrderByDescending

    Mains.GroupBy(l => l.ContactID)
        .Select(g => g.OrderByDescending(l => l.ID).First())
        .ToList();
    

    另外,从组中选择项目时不需要FirstOrDefault;一个组将始终至少有一个项目,因此您可以安全地使用First()

    【讨论】:

    • 更短的版本:g => g.OrderBy(l => l.ID).Last() :)
    【解决方案3】:

    也许选择Max而不是OrderByDescending可能会提高性能(我不确定它是如何在内部制造的,因此需要对其进行测试):

    var grouped = Mains.GroupBy(l => l.ContactID);
    var ids = grouped.Select(g => g.Max(x => x.Id));
    var result = grouped.Where(g => ids.Contains(g.Id));
    

    我认为这可能会导致查询将采用 MAX 然后执行 SELECT * FROM ... WHERE id IN ({max ids here}) 这可能比 OrderByDescending 快得多。

    如果我说的不对,欢迎指正。

    【讨论】:

    • 比 OrderBy 胖
    • 最后一行应该是...吗? var 结果 = Mains.Where(g => ids.Contains(g.Id));
    【解决方案4】:

    降序排列

    Mains.GroupBy(l => l.ContactID)
    .Select(g=>g.OrderByDescending(c=>c.ID).FirstOrDefault()) 
    .ToList()
    

    是你最好的解决方案

    它按照 ID 降序排列,这从名字上就很明显了。

    【讨论】:

      【解决方案5】:

      您可以像这样使用 MoreLinq 来获得更短的解决方案:

      Main.OrderByDescending(i => i.Id).DistinctBy(l => l.ContactID).ToList();
      

      【讨论】:

        猜你喜欢
        • 2017-02-09
        • 2019-09-02
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 2021-11-26
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        相关资源
        最近更新 更多