LINQ选择“max”版本的行

时间:2013-12-07 18:27:07

标签: linq linq-to-sql max

我正在使用LINQ,我试图选择每个“CaseId”中“version”列最大的行。

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

╔═════════╦══════════╦═════════╦══════════╗
║ 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);

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

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

2 个答案:

答案 0 :(得分:7)

您的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()

这个版本说:

首先,通过CaseId将Cases放入组中,为您提供以下内容:

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 => 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)

答案 1 :(得分:0)

做以下事情怎么样?它将返回一个字典,其中caseid为键,最大版本为值。

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