Ich versuche 2 Listen wie unten zu subtrahieren, assignUsers
hat 3 Datensätze und assignedUsers
hat 2 Zeilen. Nach Except
method bekomme ich noch 3 Zeilen, obwohl ich 1 Datensatz bekommen sollte, weil 2 Zeilen in assignedUsers
ähnlich zu assignUsers
Damit Except
method wie erwartet funktioniert, muss die Klasse AssignUserViewModel
die Methoden GetHashCode
und Equals
korrekt überschreiben.
Wenn beispielsweise AssignUserViewModel
-Objekte durch ihre Id
eindeutig definiert sind, sollten Sie die Klasse folgendermaßen definieren:
Andernfalls können Sie, wenn Sie die Klassenimplementierung nicht ändern können / wollen, ein IEqualityComparer<>
implementieren und es an die Methode Except
übergeben, z. :
dann würde deine letzte Zeile werden:
%Vor% Warum passiert das?
Wenn Sie Operationen setzen (Unterschiedlich, außer, Schnittmenge, Union) verwenden, müssen Sie die Sequenz vergleichen ( s) Elemente für die Gleichheit. Standardmäßig verwendet Linq Object.Equals und Object.GetHashCode Methoden zum Vergleichen von Elementen. Wenn diese Methoden in Ihrem Typ nicht überschrieben werden, wird die Implementierung der Basisklasse verwendet, die Objekte anhand der Referenzgleichheit vergleicht. Die Standardimplementierung garantiert, dass zwei Objekte, die die gleiche Referenz haben, denselben Hash-Code haben (also als gleichwertig betrachtet werden). Das ist dein Fall. Mapper
class erstellt neue Instanzen von AssignUserViewModel
-Objekten, die unterschiedliche Referenzen haben und nicht als gleich behandelt werden können (auch wenn alle Feldwerte gleich sind).
Also, was könnten wir damit machen?
Überschreiben Sie die Methoden Equals
und GetHashCode
in Ihrer Klasse. Es liegt an Ihnen, wie Sie die Gleichheit der Objekte behandeln - alle Felder oder nur die Identität. Linq verwendet Ihre Methoden zum Vergleichen von Elementen.
Geben Sie Ihren eigenen Vergleicher an (dies ist in der Regel der Fall, wenn Sie Ihr Objekt nicht ändern und Equals
und GetHashCode
überschreiben können. Ja, alle Linq-Set-Operationen haben zwei Überladungen - eine verwendet Standardkomparator und andere, welches deine akzeptiert IEqualityComparer<T>
.
Verwenden Sie anonyme Typen. Alle anonymen Typen haben bereits die Methoden Equals
und GetHashCode
generiert, die einen Vergleich aller Eigenschaften verwenden, um festzustellen, ob Objekte gleich sind. In diesem Fall müssen Sie weder Ihren Typ ändern noch einen Vergleicher erstellen.
Sie haben also bereits Beispiele für die ersten zwei Ansätze, hier ist der letzte:
%Vor%