Warum bekomme ich unterschiedliche Ergebnisse von zwei fast gleichen Ausdrücken, um Daten aus der Datenbank mit dem Entity Framework-Kontext zu erhalten

7

Ich validiere Benutzername (Groß-und Kleinschreibung nicht) und Passwort (Groß-und Kleinschreibung) aus der Datenbank

Ich verwende Entity Framework 5.0 zur Interaktion mit der Datenbank

In der Datenbank ist das Passwort

  

"0x11A46971EFF1E1A2CA228CF592CA37DC77E7CCF759602D53629C22B693AEEE96CCD9F889D8E9A92C19391E6BD2DD07E741E9B7AA07E391ACDC939B993C9D7F5D"

Ich erwarte null als Gegenleistung für meinen folgenden Codeblock, wenn ich die Groß- / Kleinschreibung des Passwortes auf niedriger setze, d. h.

  

"0x11a46971eff1e1a2ca228cf592ca37dc77e7ccf759602d53629c22b693aeee96ccd9f889d8e9a92c19391e6bd2dd07e741e9b7aa07e391acdc939b993c9d7f5d"

aber es schlägt nicht fehl und gibt die richtige Benutzereinheit zurück.

%Vor%

Während, wenn ich alle Benutzer bekomme und dann vergleiche gibt es eine korrekte Ausgabe, d. h. user == null

%Vor%

Das ist seltsam? Warum passiert es? Wie schreibe ich Groß-und Kleinschreibung sensible Abfrage von LINQ zu SQL?

    
Imran Rizvi 24.05.2013, 12:22
quelle

6 Antworten

2

Bei der SQL-Suche wird nicht zwischen Groß- und Kleinschreibung unterschieden. Wenn Sie ToList zuerst eingeben, wird eine Groß- und Kleinschreibung berücksichtigt. Aber der ToList wird alles aus der DB zurückgeben. Stattdessen führen Sie die Where auf der db und dann einen weiteren Vergleich, um sicherzustellen, dass das Passwort der richtige Fall ist.

%Vor%     
juharr 24.05.2013, 13:01
quelle
12

SQL unterscheidet nicht zwischen Groß- und Kleinschreibung. Wenn Sie sich das generierte SQL ansehen, sieht es etwa so aus:

%Vor%

Es wird unabhängig vom Fall wahr zurückgegeben. Das zweite Beispiel ruft ToList auf, so dass es jetzt einen .net String vergleicht, was Groß- und Kleinschreibung unterscheidet.

    
pingoo 24.05.2013 12:29
quelle
7

Bei Verwendung von

%Vor%

Sie arbeiten an einer Lazyloaded EntityCollection. Da SQL nicht zwischen Groß- und Kleinschreibung unterscheidet, wird es jedes Mal als wahr zurückgegeben.

Wenn Sie

verwenden %Vor%

Sie wechseln von LINQ To Entities zu LINQ To Objects , sodass Sie jetzt einen Vergleich zwischen Groß- und Kleinschreibung vornehmen können.

Der große Nachteil ist, dass jedes Mal, wenn Sie ToList() verwenden, Ihre Query sofort ausgeführt wird und Sie die COMPLETE-Liste der Benutzer aus der Datenbank laden.

    
Johannes Wanzek 24.05.2013 12:29
quelle
2

Wie schon erwähnt, liegt das daran, dass Ihre Datenbank so konfiguriert ist, dass sie Groß- und Kleinschreibung nicht vergleicht. Das folgende kleine Programm zeigt, wie EF die an StringComparison übergebenen String.Equals Werte vollständig ignoriert. Es zeigt auch, wie das Ändern der Sortierung der Datenbankspalte das erreicht, was Sie brauchen.

Dies ist ein wichtiges Konzept beim Arbeiten mit EF (und anderen LINQ-Anbietern). Ihre Abfrage, wie sie geschrieben wird sieht wie normaler .NET-Code aus. Es ist jedoch nicht! Viele Anbieter übersetzen den Code in etwas völlig anderes, in diesem Fall SQL (für SQL Server, Transact-SQL). Nur eine Untermenge der verfügbaren .NET-Methoden funktioniert überhaupt (weshalb Sie zum Beispiel Regex in einer EF-Abfrage nicht verwenden können), und diejenigen, die funktionieren, weisen möglicherweise ein subtil anderes Verhalten auf als das, was Sie tun würden erwarten.

Wenn Sie ToList() für eine Abfrage verwenden, dann Ihren Filter anwenden, verwenden Sie LINQ to Objects, nicht EF, um den Filter anzuwenden. LINQ to Objects ist "real" .NET, so dass Sie die gesamte Palette von .NET-Funktionen zur Verfügung haben. Natürlich verlieren Sie den Vorteil, dass Ihr Code auf dem SQL Server ausgeführt wird, daher ist dies normalerweise keine Option.

%Vor%     
Olly 24.05.2013 13:15
quelle
1

Hier gibt es eine ausführlichere Antwort:

Ссылка

Bei Bedarf können Sie die Spalte auf der Serverseite so konfigurieren, dass Groß- und Kleinschreibung beachtet wird. Aber in Ihrem Fall sehe ich nicht, warum Sie das Passwort überhaupt abfragen müssen. Sicherlich gibt es nur ein Passwort für jeden Benutzernamen, und ein Benutzername sollte nicht zwischen Groß- und Kleinschreibung unterscheiden. Warum also nicht einfach nach dem Benutzernamen suchen und dann das Passwort auf dem Ergebnis überprüfen?

    
nmclean 24.05.2013 13:01
quelle
-1

Wie alle anderen bereits erwähnt haben, liegt die Ursache des Problems darin, dass SQL Server standardmäßig keine Groß- und Kleinschreibung berücksichtigt und C # standardmäßig Groß- und Kleinschreibung berücksichtigt.

Sie können das Kennwortfeld von varchar nach varbinary ändern, um dieses Problem zu umgehen.

Warum die anonymen Stimmen runter? Die Verwendung einer Zeichenfolge zum Speichern und Vergleichen eines scheinbar 64-Byte-Hashwerts ist nicht der beste Ansatz. Es ist nicht notwendig, einen Hash zu codieren, um ihn zu speichern (es sei denn Entity Framework kann damit nicht umgehen?).

Ссылка Vergleichen von Hash-Passwörtern

    
qujck 24.05.2013 13:49
quelle

Tags und Links