在其中一个属性中获取具有最大日期时间值的对象

时间:2013-03-11 09:40:18

标签: c# linq

当我想从DateTime检索IEnumerable属性中具有最高值的对象时,我可以执行以下操作:

var maxDate = myEnumerable.Max(x => x.TheDateTimeProperty);
var wantedObject = myEnumerable.FirstOrDefault(x => x.TheDateTimeProperty == maxDate);

这是否可以在不先获得maxDate的情况下实现?例如:

var wantedObject = myEnumerable.GetByMaxDate(x => x.TheDateTimeProperty);

我知道我可以编写扩展方法GetByMaxDate,但我想知道linq是否已经提供了一种方法。

只是为了澄清:没有寻找其他可能来写这个。如果存在一种方法,我只是感兴趣。 (代码少,代码管理的最佳性能)

3 个答案:

答案 0 :(得分:11)

Pro:它应该与“any”linq提供程序(对象,实体,sql)一起使用

myEnumerable.OrderByDescending(x => x.TheDateTimeProperty).First();

Con:正如Matthew Watson在评论中指出的那样,它不会在(非常)大型名单上表现出色。

答案 1 :(得分:2)

我更喜欢像你原先说的那样首先获得maxDate。使用您已使用的语法时,我没有看到任何问题。

但是如果你想要,你可以像这样简写代码:

var wantedObject = myEnumerable.FirstOrDefault(x => x.TheDateTimeProperty == myEnumerable.Max(x => x.TheDateTimeProperty));

(此代码未经过测试,可能需要进行某些类型的转换)

或者您可以编写存储过程并从中获取数据。

但我不再喜欢OrderByDescending.First了。如果物理上表中的数据按指定的属性递增排序,则可以。但如果没有,那么你的sql表将需要进行降序排序,并可能从中获得高负载。特别是当表具有超过1m的记录并且DateTime以物理上升的方式存储时。

使用max可以获得比它更好(更快/更轻)的结果。

答案 2 :(得分:0)

由于没有其他答案,在linq中存在内置方法,我会写下我将使用的内容。

对于linq到对象:

Habib在评论中提到的来自morelinq的方法MaxBy

对于linq to sql:

我会写一个扩展方法。我试过这个,但是下面的代码还没有用。 如果有人知道什么是错的,请编辑答案。我有空的时候会尝试搞清楚。

public static TSource SqlMaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{   
  var maxValue = source.Max(selector);
  return source.FirstOrDefault(selector == maxValue);
}