【问题标题】:LINQ Select rows mith "max" versionLINQ 选择具有“最大”版本的行
【发布时间】:2014-05-12 21:12:15
【问题描述】:

我正在使用 LINQ,并尝试选择每个“CaseId”的“版本”列最大的行。

这是一个包含数据的示例表:

╔═════════╦══════════╦═════════╦══════════╗
║ Id      ║ CaseId   ║ Version ║ ParentId ║
╠═════════╬══════════╬═════════╬══════════╣
║ 1       ║ A        ║    0    ║          ║
║ 2       ║ A        ║    1    ║    1     ║
║ 3       ║ A        ║    2    ║    2     ║
║ 4       ║ B        ║    0    ║          ║
║ 5       ║ B        ║    1    ║    4     ║
║ 6       ║ C        ║    0    ║          ║
╚═════════╩══════════╩═════════╩══════════╝

期望的结果是:

╔═════════╦══════════╦═════════╦══════════╗
║ Id      ║ CaseId   ║ Version ║ ParentId ║
╠═════════╬══════════╬═════════╬══════════╣
║ 3       ║ A        ║    2    ║    2     ║
║ 5       ║ B        ║    1    ║    4     ║
║ 6       ║ C        ║    0    ║          ║
╚═════════╩══════════╩═════════╩══════════╝

我使用的 LINQ 如下:

IEnumerable<Case> list =
    (from c in db.DBCases
     let maxVersion = db.DBCases.Max(c => c.Version)
     where (c.Version == maxVersion)
     orderby c.CaseId descending
     select c);

这目前仅返回具有整个表最大版本的行,但省略了所有其他记录。

╔═════════╦══════════╦═════════╦══════════╗
║ Id      ║ CaseId   ║ Version ║ ParentId ║
╠═════════╬══════════╬═════════╬══════════╣
║ 3       ║ A        ║    2    ║    2     ║
╚═════════╩══════════╩═════════╩══════════╝

【问题讨论】:

    标签: linq linq-to-sql max


    【解决方案1】:

    您的where 子句告诉它准确地得到您所说的(只有Cases 的版本等于整个表的最大版本)。这样想:

    // This is 2.
    int maxVersionOfWholeTable = db.DBCases.Max(c => c.Version);
    
    // This is essentially what your query is doing:
    var query = from c in db.DBCases
                where c.Version == maxVersionOfWholeTable
                select c;
    

    相反,您可以使用分组来实现所需的结果:

    var query = from c in db.DBCases
                group c by c.CaseId into g
                orderby g.Key descending
                select g.OrderByDescending(x => x.Version).FirstOrDefault()
    

    这个版本说:

    首先,将 Cases 按 CaseId 分组,给你这样的东西:

    Group 1 (CaseId = A): 1, 2, 3
    Group 2 (CaseId = B): 4, 5
    Group 3 (CaseId = C): 6
    

    然后对于每个组,按版本排序并获得最高记录,如下所示:

    Group 1 Ordered: [3], 2, 1
    Group 2 Ordered: [5], 4
    Group 3 Ordered: [6]
    

    导致:3、5、6。

    编辑 - 回到这个问题并意识到g.OrderByDescending(x =&gt; x.Version).FirstOrDefault() 行可以很好地解释发生了什么,但在这种情况下使用Max() 会更清楚一些,如下所示:

    var query = from c in db.DBCases
                group c by c.CaseId into g
                orderby g.Key descending
                select g.Max(x => x.Version)
    

    【讨论】:

    • 没问题。如果您还没有它,请在 LinqPad 中寻找一个奇妙的沙盒环境,您可以在其中玩查询并获得正在发生的事情的快速视觉反馈。
    • @Ocelot20 - 如果您说有一个 Case { Id; 类型的对象,您将如何将查询表达式与投影结合起来案例ID;版本; ParentId} ?
    【解决方案2】:

    如何做类似以下的事情。它将返回一个以 caseid 为键、最大版本为值的字典。

           list.GroupBy(x => x.CaseId).ToDictionary(x => x.Key, x => x.Max(c => c.Version));
    

    【讨论】:

      猜你喜欢
      • 2023-02-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2021-07-21
      • 2021-08-10
      • 1970-01-01
      • 2017-10-03
      相关资源
      最近更新 更多