2013-03-11 13 views
7

Wenn ich ein Objekt mit dem höchsten Wert in einer DateTime Eigenschaft von einem IEnumerable abrufen möchten, kann ich folgendes tun:Erste Objekt mit max Datum Zeitwert in einer seiner Eigenschaften

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

Ist das möglich ohne zuerst die maxDate zu bekommen? Zum Beispiel wie folgt aus:

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

Ich weiß, dass ich eine Erweiterungsmethode schreiben konnte GetByMaxDate, aber ich möchte wissen, ob es bereits eine Methode, mit Linq vorgesehen ist.

Nur um zu klären: Nicht auf der Suche nach anderen Möglichkeiten, dies zu schreiben. Ich war nur interessiert, ob es eine Methode gibt, die das tut. (Weniger Code, möglich beste Leistung durch das Verfahren verwaltet)

+2

Sie können [morelinq] (https://code.google.com/p/morelinq /) von Jon Skeet und seine Methode [MaxBy] (https://code.google.com/p/morelinq/source/browse/MoreLinq/MaxBy.cs?r=2da75c30d5bda7959e5113b702b4bb204a0e4a2c) – Habib

+0

Ich zweite der Begriff dass Sie die MaxBy-Methode von morelinq verwenden sollten. Sollte in jedem C# Programmierer Toolbox sein! –

+0

Also, es gibt keine Einbaumethode von linq, danke für die Information über diese! –

Antwort

0

Da es kommen keine anderen Antworten und es existiert kein build-in Verfahren in Linq, werde ich aufschreiben, was ich verwenden würde.

Für Linq zu Objekten:

Verfahren MaxBy von morelinq wie von Habib im Kommentar erwähnt.

für LINQ to SQL:

Ich würde eine Verlängerung Methode schreiben. Ich habe es versucht, aber der folgende Code funktioniert noch nicht. Wenn jemand weiß, was falsch ist, bearbeiten Sie bitte die Antwort. Ich werde versuchen, es herauszufinden, wenn ich etwas Zeit habe.

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

Pro: Es sollte mit "jeder" Linq-Anbieter arbeiten (Objekte, Entitäten, sql)

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

Con: wie von Matthew Watson in Kommentaren darauf , es wird nicht auf (sehr) großen Listen performant sein.

+0

Dies hat den großen Nachteil, dass es eine Kopie der gesamten Sequenz macht, dann sortiert es nur, um den maximalen Wert zu erhalten. Gut für kleine Listen ... sehr sehr schlecht für lange Listen. –

+0

@MatthewWatson absolut. Nur eine Frage (wenn Sie die Antwort haben), arbeitet MaxBy an allen Linq Providern, wie Linq an Entitäten? Mit dem gegebenen Quellcode sieht es so aus, als ob es aufzählt, was ... für ein IQueryable nicht großartig ist. –

+0

Nicht genau das, was ich suchte, das wird mir das Ergebnis bringen, aber ich war interessiert, ob es eine Methode gibt, die ich verwenden kann (mit guter Leistung) –

2

Ich bevorzuge die MaxDate zuerst wie Sie ursprünglich angegeben haben. Ich sehe kein Problem mit der Syntax, die Sie bereits verwendet haben.

jedoch wünschen, wenn Sie den Code wie dieser Kurzschrift kann:

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

(Dieser Code ist nicht getestet, vielleicht eine Art Casting erforderlich)

Oder Sie können eine gespeicherte Prozedur schreiben und nehmen die Daten davon.

Allerdings bevorzuge ich OrderByDescending.First nicht mehr. Es ist in Ordnung, wenn Ihre Daten in der Tabelle aufsteigend nach Ihrer angegebenen Eigenschaft sortiert sind. Aber wenn nicht, dann muss Ihre SQL-Tabelle eine absteigende Sortierung durchführen und wahrscheinlich eine hohe Last daraus erhalten. Vor allem, wenn die Tabelle mehr als 1 Mio. Datensätze hat und die DateTime im Physical aufsteigend gespeichert wird.

Verwenden Sie maximal kann Ergebnis besser (schneller/leichtes) Ergebnis als es.

+0

Ich wollte nicht fragen, ob es einen anderen Weg gibt, ohne zuerst das maxDate in einer Variablen zu speichern . Ich werde meine Frage bearbeiten, um das zu klären. –

+0

Ja, ich weiß, nur die Kurzschrift als zusätzliche anzeigen. Nach meinem Verständnis, was Sie bereits gut und leicht genug erreicht haben. Vielleicht können Sie besser antworten, wenn Sie Ihr Problem mit der Syntax beschrieben haben. Wenn Sie jedoch bessere Ergebnisse erzielen möchten, sollten Sie die gespeicherte Prozedur verwenden, in der Sie die Abfrage optimieren oder mit Indizes verbessern können. – Fendy

+0

Meine Frage ist nicht speziell über LINQ-zu-SQL, aber wenn jemand es in diesem Zusammenhang will, ist das ein guter Punkt! –

Verwandte Themen