结合两个LINQ查询的优雅方式

时间:2011-08-26 17:54:16

标签: c# linq

如何将这两个LINQ查询合并为一个?

var maxEndDate = lstDates.Select(s => s.EndDate).Max();    
var record = lstDates.Where(s => s.EndDate == maxEndDate).First();

6 个答案:

答案 0 :(得分:8)

MaxBy正是您要找的:http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/MaxBy.cs像这样使用它:

var record = lstDates.MaxBy(a => a.EndDate);

编辑1:由于 Jason 指出此方法仅在您使用LINQ to Objects时使用。如果您正在查询数据库(因此您正在使用LINQ to SQL或其他),您应该考虑使用不同的方法。

您的内容似乎非常易读,但如果它不能满足您的要求,您可以随时在AsEnumerable对象上调用IQueryable,然后使用MaxBy方法。

var record = lstDates.AsEnumerable().MaxBy(a => a.EndDate);

编辑2:您可以在查询中更改的一件事是第二个语句。尝试按如下方式缩短它(为了避免使用Where):

var record = lstDates.First(s => s.EndDate == maxEndDate);

答案 1 :(得分:2)

var record = lstDates.OrderByDescending(d => d.EndDate).First();

答案 2 :(得分:1)

请注意,实际上最好没有 LINQ。只需遍历列表,跟踪最大日期以及首次找到的项目:

DateTime maxDate = default(DateTime);
YourClass maxItem = null;

foreach (var item in lstDates)
{
    if (item.EndDate > maxDate)
    {
        maxDate = item.EndDate;
        maxItem = item;
    }
}

现在你只需要迭代一次,而不必进行排序。

这假设你正在使用LINQ-to-Objects。如果你不是,那么这将从数据库(或任何地方)检索整个集合,这是不合需要的。在这种情况下,我会使用你已经拥有的方法。

答案 3 :(得分:1)

var record = (from r in lstDates
              orderby r.EndDate descending
              select r).First();

答案 4 :(得分:1)

对于链接到对象(Linq-to-Sql中不支持聚合)。执行N(n)(好的,实际上是O(n + 1))

var record = lstDates.Aggregate(lstDates.First(), 
                                (mx, i) => i.EndDate > mx.EndDate ? i : mx));

对于那些在阅读时遇到问题的人,第一个参数是累加器的初始值,这将正常聚合列表中的值,但这里只是保持当前最高记录。然后,对于列表中的每个记录,在给定当前最高项和下一项的情况下调用lambda函数。它返回新的当前最高值。

答案 5 :(得分:-1)

var record = lstDates.Where(s => s.EndDate == lstDates.Max(v => v.EndDate)).First();