Philipp M
Philipp M

Reputation: 1891

Getting object with max date time value in one of it's properties

When I want to retrieve an object with the highest value in a DateTime property from an IEnumerable, I can do the following:

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

Is this possible without getting the maxDate first? For example like this:

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

I know that I could write an extension method GetByMaxDate, but I want to know if there is already a method provided by linq.

Just to clarify: Not looking for other possibilities to write this. I was just interested if there exists a method that does it. (less code, best performance possible managed by the method)

Upvotes: 13

Views: 18221

Answers (3)

Philipp M
Philipp M

Reputation: 1891

Since there are coming no other answers and there doesn't exist a build-in method in linq, I'll write down what I would use.

For linq to objects:

The method MaxBy from morelinq as mentioned by Habib in the comment.

For linq to sql:

I would write an extension method:

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

Update:

In the .NET 9 Preview there was added a MaxBy method.

Upvotes: 0

Rapha&#235;l Althaus
Rapha&#235;l Althaus

Reputation: 60493

Pro : it should work with "any" linq provider (objects, entities, sql)

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

Con : as pointed by Matthew Watson in comments, it won't be performant on (very) large lists.

Upvotes: 14

Fendy
Fendy

Reputation: 4643

I prefer to get the maxDate first like you have stated originally. I don't see any problem using the syntax you already used.

However if want you can shorthand the code like this:

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

(This code is not tested, maybe some type casting is needed)

Or you can write a stored procedure and take the data from that.

However I don't prefer OrderByDescending.First anymore. It is fine if physically your data in table is sorted ascending by your specified property. But if not, then your sql table will need to do descending sorting and probably get high load from it. Especially when the table has over than 1m record and the DateTime is stored ascending in the physical.

Use max can resulting better (faster/lightweight) result than it.

Upvotes: 2

Related Questions