• Fabian Wetzel
  • 2011-01-30
  • 2 min. read

Distinct und die dunkle Seite!

Im Projekt war aufgefallen, dass eine Komponente, die Key/Value Werte aus Nachrichten extrahiert, die Paare doppel extrahiert, wenn sie denn doppelt in der Nachricht sind und letztlich wurden die Paare dann auch mehrfach zu einer Nachricht in der Datenbank hinterlegt. Mangels Mehrwert war nun die Idee, die Doppelten zu löschen. Vor dem Abspeichern in LINQ ein Distinct aufgerufen zusammen mit einer Standardimplementierung von IEqualityComparer und gut war.

Über ein einmaliges Skript auch die Doppelten aus der Datenbank entfernt, einen UNIQUE-Index angelegt und gut.

Und gut? Am nächsten Tag ging einen halben Tag lang nichts mehr. Die Komponente war an sich getestet, aber der Fall der aufgetreten war, war, dass die Datenbank in Form des MS SQL Server Gleichheit viel weitreichender definiert, als mein Code es tat, so kam es, dass der UNIQUE-Index Transaktionen zurück rollte, die eigentlich nur distinkte Paare enthielt.

Was war passiert? Im C#-Code hatte ich Equals über String.Equals implementiert. Der SQL Server entscheidet bei Gleichheit aber ohne Betrachtung der Groß-/Kleinschreibung. Während des Entwickelns des Bugfixes ist dann noch aufgefallen, dass der SQL Server auch “ss” und “ß” als gleich betrachtet.

Geholfen hatte auf Stackoverflow die Antwort von cdhowie. Die generische Lösung unterstützt dabei auch noch immer GetHashCode, da sonst die Performance leidet:

1
String.Equals(a.Description, b.Description, StringComparison.OrdinalIgnoreCase);

und

1
StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Description);