我有一个如下课程:
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。
答案 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)));
尝试使用FirstOrDefault
或SingleOrDefault
代替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;