从许多版本化项目中选择最新项目的LINQ是什么?

时间:2010-11-18 16:37:46

标签: linq c#-4.0 linq-to-entities

我有一个如下课程:

public class Invoice
{
    public int InvoiceId {get;set;}
    public int VersionId {get;set;}
}

每次修改Invoice时,VersionId都会增加,但InvoiceId保持不变。因此给定IEnumerable<Invoice>具有以下结果:

InvoiceId VersionId
1         1
1         2
1         3
2         1
2         2

我如何才能得到结果:

InvoiceId VersionId
1         3
2         2

即。我只想从具有最新VersionId的结果中获取发票。我可以很容易地在T-SQL中做到这一点,但在我的生活中不能计算出正确的LINQ语法。我正在使用Entity Framework 4 Code First。

3 个答案:

答案 0 :(得分:1)

编辑:我已经使用LINQ to Entities测试了这两个查询。它们似乎有用,所以也许这个问题还有别的什么呢?


选项1:

var latestInvoices = invoices.GroupBy(i => i.InvoiceId)
                             .Select(group => group.OrderByDescending(i => i.VersionId)
                                                   .FirstOrDefault());

编辑:将“Last”更改为“FirstOrDefault”,LINQ to Entities在“Last”查询运算符中出现问题。


选项2:

var invoices = from invoice in dc.Invoices
               group invoice by invoice.InvoiceId into invoiceGroup
               let maxVersion = invoiceGroup.Max(i => i.VersionId)
               from candidate in invoiceGroup
               where candidate.VersionId == maxVersion
               select candidate;

答案 1 :(得分:1)

VersionId排序,按InvoiceId分组,然后获取每组的第一个结果。试试这个:

var query = list.OrderByDescending(i => i.VersionId)
                .GroupBy(i => i.InvoiceId)
                .Select(g => g.First());

编辑:使用Max的方法怎么样?

var query = list.GroupBy(i => i.InvoiceId)
                .Select(g => g.Single(i => i.VersionId == g.Max(o => o.VersionId)));

尝试使用FirstOrDefaultSingleOrDefault代替Single ......虽然Single更好地表明了意图,但它会得到相同的结果。

答案 2 :(得分:1)

我的版本:

var h = from i in Invoices
        group i.VersionId by i.InvoiceId into grouping
        select new {InvoiceId = grouping.Key, VersionId = grouping.Max()};

<强>更新

正如Ahmad在评论中所提到的,上述查询将返回一个投影。以下版本将返回IQueryable<Invoice>。我使用组合来构建查询,因为我认为它更清楚。

var maxVersions = from i in Invoices
                  group i.VersionId by i.InvoiceId into grouping
                  select new {InvoiceId = grouping.Key, 
                              VersionId = grouping.Max()};

var latestInvoices =  from i in Invoices
                      join m in maxVersions 
                      on new {i.InvoiceId, i.VersionId} equals 
                         new {m.InvoiceId, m.VersionId}
                      select i;