Frage

Ich verwende LINQ to Objects Anweisungen auf einer geordneten Anordnung. Welche Operationen sollte ich nicht tun die Reihenfolge der Anordnung sicher sein nicht geändert?

War es hilfreich?

Lösung

Ich untersuchte die Methoden der System.Linq.Enumerable , jede verwirft, die nicht IEnumerable Ergebnisse zurückgegeben. Ich überprüfte die Bemerkungen von jedem, um zu bestimmen, wie die Reihenfolge des Ergebnisses aus, um der Quelle unterscheiden würde.

Behält Absolut Order. Sie können durch den Index zu einem Ergebniselement ein Quellenelement Karte

  • AsEnumerable
  • Cast
  • Concat
  • Wählen Sie
  • ToArray
  • ToList

Behält Order. Die Elemente werden gefiltert, aber nicht nachbestellt.

  • Distinct
  • Mit Ausnahme
  • Intersect
  • OfType
  • Weiter
  • Skipwhile
  • Nehmen Sie
  • Takewhile
  • Wo
  • Zip (neu in .net 4)

Zerstört Order -. Wir nicht wissen, in welcher Reihenfolge in Ergebnisse zu erwarten

  • ToDictionary
  • ToLookup

setzt neue Maßstäbe Bestellen Explizit - verwenden diese die Reihenfolge des Ergebnisses zu ändern

  • OrderBy
  • OrderByDescending
  • Reverse-
  • ThenBy
  • ThenByDescending

setzt neue Maßstäbe Sortieren nach einigen Regeln.

  • GroupBy - Die IGrouping Objekte werden in einer Reihenfolge auf der Reihenfolge der Elemente in der Quelle ergab zugrunde, dass der erste Schlüssel jedes IGrouping hergestellt. Elemente in einer Gruppierung werden in der Reihenfolge, wie sie in der Quelle erscheinen ergeben.
  • GroupJoin - GroupJoin bewahrt die Reihenfolge der Elemente der äußeren und für jedes Element der äußeren, die Reihenfolge der Anpassungselemente von den inneren
  • .
  • Mitglied werden - bewahrt die Reihenfolge der Elemente der äußeren, und für jedes dieser Elemente, die Reihenfolge der Anpassungselemente der Innen.
  • Select -. Für jedes Element der Quelle, Selektor aufgerufen und eine Folge von Werten zurückgegeben
  • Union - Wenn das Objekt von dieser Methode zurückaufgezählt wird, aufzählt Union erster und zweite in dieser Reihenfolge ergibt, und jedes Element, das nicht schon nachgegeben wurde.

Edit: Ich habe zu bewahren, um Distinct bewegt auf dieser Basis Implementierung .

    private static IEnumerable<TSource> DistinctIterator<TSource>
      (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
        Set<TSource> set = new Set<TSource>(comparer);
        foreach (TSource element in source)
            if (set.Add(element)) yield return element;
    }

Andere Tipps

Sprechen Sie eigentlich über SQL oder über Arrays? Um es anders auszudrücken, sind Sie LINQ to SQL oder LINQ to Objects?

Die LINQ to Objects Betreiber nicht wirklich ihre ursprüngliche Datenquelle ändern - sie bauen Sequenzen, die von der Datenquelle effektiv unterstützt werden. Die einzigen Operationen, die die Reihenfolge zu ändern sind SortiertNach / OrderByDescending / ThenBy / ThenByDescending - und selbst dann, das sind stabil gleich geordneten Elemente. Natürlich werden viele Operationen einige Elemente herauszufiltern, aber die Elemente, die in der gleichen Reihenfolge sein zurückgegeben wird.

Wenn Sie auf eine andere Datenstruktur umwandeln, zum Beispiel mit ToLookup oder ToDictionary, glaube ich nicht, um an diesem Punkt erhalten bleibt - aber das ist etwas irgendwie anders. (Die Reihenfolge der Werte-Mapping auf den gleichen Schlüssel ist allerdings für Lookups erhalten, glaube ich.)

Wenn Sie auf einem Array arbeiten, es klingt wie Sie mit LINQ-to-Objects, nicht SQL; Kannst du bestätigen? Die meisten LINQ Operationen erneut um etwas nicht (die Ausgabe in der gleichen Reihenfolge wie der Eingang sein wird.) - so gelten nicht eine andere Art (SortiertNach [absteigend] / ThenBy [absteigend])

[edit: wie Jon deutlicher setzen; LINQ schafft im Allgemeinen ein neue Sequenz, die ursprünglichen Daten allein lassend]

Beachten Sie, dass die Daten in eine Dictionary<,> (ToDictionary) drückt die Daten verschlüsseln, als Wörterbuch keine bestimmte Reihenfolge, um nicht respektiert.

Aber häufigstene Dinge (Select, wo, Überspringen, Take) sollte in Ordnung sein.

fand ich eine große Antwort auf eine ähnliche Frage, die offizielle Dokumentation verweist. Zitieren sie:

Für Enumerable Methoden (LINQ to Objects, die List<T> gilt), können Sie auf die Reihenfolge der Elemente verlassen zurück von Select, Where oder GroupBy. Dies ist nicht der Fall für Dinge, die von Natur aus ungeordneten sind wie ToDictionary oder Distinct.

  

Enumerable.GroupBy Dokumentation:

     

Die IGrouping<TKey, TElement> Objekte werden in einer Reihenfolge auf der Reihenfolge der Elemente in der Quelle ergab zugrunde, dass der erste Schlüssel jedes IGrouping<TKey, TElement> hergestellt. Elemente in einer Gruppierung werden in der Reihenfolge ergeben sie in source erscheinen.

Dies ist nicht unbedingt wahr für IQueryable Erweiterungsmethoden (andere LINQ-Provider).

Quelle: Enumerable Methoden LINQ Sie relative Reihenfolge beibehalten die Elemente?

Jede ‚Gruppe‘ oder ‚Ordnung durch‘ wird möglicherweise die Reihenfolge ändern.

Die Frage bezieht sich hier speziell auf LINQ-to-Objects.

Wenn Ihr mit LINQ-to-SQL stattdessen gibt es keine Ordnung gibt, wenn Sie ein mit etwas aufzwingen wie:

mysqlresult.OrderBy(e=>e.SomeColumn)

Wenn Sie tun dies nicht mit LINQ-to-SQL dann der Reihenfolge der Ergebnisse zwischen dem nachfolgenden Abfragen sogar den gleichen Daten variieren kann, die einen intermittierenden Fehler verursachen könnten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top