Ich möchte eine solche Abfrage ausführen
var result = from entry in table
where entry.something == null
select entry;
und erhalten eine IS NULL
generierte.
Bearbeitet: Nach den ersten beiden Antworten muss klargestellt werden, dass ich Entity Framework und nicht Linq to SQL verwende. Die object.Equals () -Methode scheint in EF nicht zu funktionieren.
Edit Nr. 2: Die obige Abfrage funktioniert wie vorgesehen. Es wird korrekt generiert IS NULL
. Mein Produktionscode war jedoch
value = null;
var result = from entry in table
where entry.something == value
select entry;
und das generierte SQL war something = @p; @p = NULL
. Es scheint, dass EF den konstanten Ausdruck korrekt übersetzt, aber wenn eine Variable beteiligt ist, behandelt sie ihn wie einen normalen Vergleich. Macht eigentlich Sinn. Ich werde diese Frage schließen
.net
entity-framework
ado.net
Adrian Zanescu
quelle
quelle
Antworten:
Problemumgehung für Linq-to-SQL:
Problemumgehung für Linq-to-Entities (autsch!):
Dies ist ein böser Fehler, der mich mehrmals gebissen hat.
Wenn dieser Fehler auch Sie betroffen hat, besuchen Sie bitte den Fehlerbericht auf UserVoice und teilen Sie Microsoft mit, dass dieser Fehler auch Sie betroffen hat.Bearbeiten: Dieser Fehler wird in EF 4.5 behoben ! Vielen Dank an alle für das Upvoting dieses Fehlers!
Aus Gründen der Abwärtskompatibilität wird die Option aktiviert. Sie müssen eine Einstellung manuell aktivieren, damit sie
entry == value
funktioniert. Noch kein Wort darüber, was diese Einstellung ist. Bleib dran!Edit 2: Nach diesem Beitrag des EF-Teams wurde dieses Problem in EF6 behoben! Woohoo!
Dies bedeutet, dass vorhandener Code, der sich auf das alte Verhalten stützt (
null != null
jedoch nur beim Vergleich mit einer Variablen) , entweder geändert werden muss, um sich nicht auf dieses Verhalten zu verlassen, oderUseCSharpNullComparisonBehavior
auf false gesetzt werden muss, um das alte fehlerhafte Verhalten zu verwenden.quelle
(var result = from ...; if(value.HasValue) result = result.Where(e => e.something == value) else result = result.Where(e => e.something == null);
(where Object.Equals(entry.something,value))
Seit Entity Framework 5.0 können Sie folgenden Code verwenden, um Ihr Problem zu lösen:
Dies sollte Ihre Probleme lösen, da Entity Framerwork den Nullvergleich "C # like" verwendet.
quelle
Es gibt eine etwas einfachere Problemumgehung, die mit LINQ to Entities funktioniert:
Dies funktioniert, weil, wie AZ feststellte, LINQ to Entities-Sonderfälle x == null (dh ein Gleichheitsvergleich mit der Nullkonstante) und in x IS NULL übersetzt werden.
Wir erwägen derzeit, dieses Verhalten zu ändern, um die Kompensationsvergleiche automatisch einzuführen, wenn beide Seiten der Gleichheit nullbar sind. Es gibt jedoch einige Herausforderungen:
Ob wir daran arbeiten können, hängt in jedem Fall stark von der relativen Priorität ab, die unsere Kunden ihm zuweisen. Wenn Sie sich für das Problem interessieren, empfehlen wir Ihnen, auf unserer neuen Website mit Funktionsvorschlägen dafür zu stimmen: https://data.uservoice.com .
quelle
Wenn es sich um einen nullbaren Typ handelt, versuchen Sie möglicherweise, die HasValue-Eigenschaft zu verwenden.
Ich habe hier allerdings keine EF zum Testen ... nur ein Vorschlag =)
quelle
== null
ohnehin nicht vom Fehler getroffen. Der Punkt besteht darin, nach dem Wert einer Variablen zu filtern, deren Wert möglicherweise null ist, und den Nullwert die Nulldatensätze finden zu lassen.(x => x.Column == null)
funktionieren. :)System.NullReferenceException
, da das Objekt bereits null ist!MSDN-Referenz : LINQ to SQL: .NET-integrierte Sprachabfrage für relationale Daten
quelle
um mit Nullvergleichen umzugehen, verwenden Sie
Object.Equals()
statt==
Überprüfen Sie diese Referenz
quelle
null
,Object.Equals(null)
was passiert , wenn dieObject
selbst ist null?Es wird darauf hingewiesen, dass alle Entity Framework <6.0-Vorschläge etwas umständliches SQL erzeugen. Siehe zweites Beispiel für "saubere" Korrektur.
Lächerliche Problemumgehung
Ergebnisse in SQL wie:
Unverschämte Problemumgehung
Wenn Sie saubereres SQL generieren möchten, können Sie Folgendes tun:
ergibt in erster Linie das, was Sie wollten:
quelle
Die obige Abfrage funktioniert wie vorgesehen. Es generiert korrekt IS NULL. Mein Produktionscode war jedoch
und das generierte SQL war etwas = @p; @p = NULL. Es scheint, dass EF den konstanten Ausdruck korrekt übersetzt, aber wenn eine Variable beteiligt ist, behandelt sie ihn wie einen normalen Vergleich. Macht eigentlich Sinn.
quelle
Es scheint, dass Linq2Sql auch dieses "Problem" hat. Es scheint, dass es einen gültigen Grund für dieses Verhalten gibt, weil ANSI NULLs EIN oder AUS sind, aber es verwirrt den Verstand, warum eine gerade "== null" tatsächlich so funktioniert, wie Sie es erwarten würden.
quelle
Persönlich bevorzuge ich:
Über
weil es Wiederholungen verhindert - obwohl das mathematisch nicht genau ist, aber es passt in den meisten Fällen gut.
quelle
Ich kann den Beitrag von divega nicht kommentieren, aber unter den verschiedenen hier vorgestellten Lösungen produziert die Lösung von divega das beste SQL. Sowohl in Bezug auf die Leistung als auch in Bezug auf die Länge. Ich habe gerade mit SQL Server Profiler nachgesehen und mir den Ausführungsplan angesehen (mit "SET STATISTICS PROFILE ON").
quelle
Leider ist das Problem in Entity Framework 5 DbContext immer noch nicht behoben.
Ich habe diese Problemumgehung verwendet (funktioniert mit MSSQL 2012, aber die Einstellung ANSI NULLS ist in zukünftigen MSSQL-Versionen möglicherweise veraltet).
Es sollte beachtet werden, dass es sich um eine schmutzige Problemumgehung handelt, die jedoch sehr schnell implementiert werden kann und für alle Abfragen funktioniert.
quelle
Wenn Sie die Methodensyntax (Lambda) wie ich bevorzugen, können Sie Folgendes tun:
quelle
verwende das
quelle