Chcę wykonać takie zapytanie
var result = from entry in table
where entry.something == null
select entry;
i uzyskaj IS NULL
wygenerowany plik .
Edytowano: Po pierwszych dwóch odpowiedziach czuję potrzebę wyjaśnienia, że używam Entity Framework, a nie Linq to SQL. Wydaje się, że metoda object.Equals () nie działa w EF.
Edycja nr 2: powyższe zapytanie działa zgodnie z zamierzeniami. Generuje poprawnie IS NULL
. Jednak mój kod produkcyjny był
value = null;
var result = from entry in table
where entry.something == value
select entry;
a wygenerowany kod SQL to something = @p; @p = NULL
. Wydaje się, że EF poprawnie tłumaczy stałe wyrażenie, ale jeśli zaangażowana jest zmienna, traktuje ją tak jak normalne porównanie. Właściwie to ma sens. Zamknę to pytanie
.net
entity-framework
ado.net
Adrian Zanescu
źródło
źródło
Odpowiedzi:
Obejście problemu z Linq-to-SQL:
Obejście problemu z linq-to-Entities (ouch!):
To paskudny błąd, który ugryzł mnie kilka razy.
Jeśli ten błąd dotyczy również Ciebie, odwiedź raport o błędzie w witrynie UserVoice i poinformuj firmę Microsoft, że ten błąd dotyczy również Ciebie.Edycja: ten błąd jest naprawiany w EF 4.5 ! Dziękujemy wszystkim za głosowanie za tym błędem!
Aby zapewnić kompatybilność wsteczną, będzie to opt-in - musisz ręcznie włączyć ustawienie, aby
entry == value
działało. Nie wiadomo jeszcze, czym jest to ustawienie. Bądźcie czujni!Edycja 2: Zgodnie z tym postem zespołu EF, ten problem został rozwiązany w EF6! Woohoo!
Oznacza to, że istniejący kod, który opiera się na starym zachowaniu (
null != null
ale tylko przy porównywaniu ze zmienną), będzie musiał zostać zmieniony, aby nie polegał na tym zachowaniu, lub ustawićUseCSharpNullComparisonBehavior
na fałsz, aby używać starego zepsutego zachowania.źródło
(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))
Od Entity Framework 5.0 możesz użyć następującego kodu w celu rozwiązania problemu:
Powinno to rozwiązać twoje problemy, ponieważ Entity Framerwork użyje porównania zerowego w języku C #.
źródło
Istnieje nieco prostsze obejście, które działa z LINQ to Entities:
Działa to, ponieważ, jak zauważyła AZ, LINQ to Entities przypadki specjalne x == null (tj. Porównanie równości ze stałą zerową) i tłumaczy to na x IS NULL.
Obecnie rozważamy zmianę tego zachowania, aby automatycznie wprowadzić porównania kompensujące, jeśli obie strony równości nie dopuszczają wartości null. Jest jednak kilka wyzwań:
W każdym razie to, czy zajmiemy się tym, będzie w dużej mierze zależało od względnego priorytetu, jaki nadadzą temu klienci. Jeśli zależy Ci na tym problemie, zachęcam do zagłosowania na niego w naszej nowej witrynie z sugestiami dotyczącymi funkcji: https://data.uservoice.com .
źródło
Jeśli jest to typ dopuszczający wartość null, może spróbuj użyć właściwości HasValue?
Nie mam tutaj żadnego EF do przetestowania ... tylko sugestia =)
źródło
== null
tak nie zostanie trafione przez błąd. Chodzi o to, aby filtrować według wartości zmiennej, której wartość może być pusta, i mieć wartość null, aby znaleźć puste rekordy.(x => x.Column == null)
pracy. :)System.NullReferenceException
, ponieważ obiekt już jest zerowy!Dokumentacja MSDN : LINQ to SQL: zapytanie o dane relacyjne zintegrowane z językiem .NET
źródło
aby poradzić sobie z pustymi porównaniami użyj
Object.Equals()
zamiast==
sprawdź to odniesienie
źródło
null
,Object.Equals(null)
co, jeśliObject
sam jest zerowy?Wskazanie, że wszystkie sugestie dotyczące Entity Framework <6,0 generują niezręczny kod SQL. Zobacz drugi przykład „czystej” poprawki.
Niedorzeczne obejście
wyniki w SQL, takie jak:
Oburzające obejście
Jeśli chcesz wygenerować czystszy SQL, coś takiego:
skutkuje tym, czego chciałeś w pierwszej kolejności:
źródło
Powyższe zapytanie działa zgodnie z przeznaczeniem. Prawidłowo generuje IS NULL. Jednak mój kod produkcyjny był
a wygenerowany SQL był czymś = @p; @p = NULL. Wydaje się, że EF poprawnie tłumaczy stałe wyrażenie, ale jeśli zaangażowana jest zmienna, traktuje ją tak, jak normalne porównanie. Właściwie to ma sens.
źródło
Wydaje się, że Linq2Sql również ma ten „problem”. Wygląda na to, że istnieje uzasadniony powód takiego zachowania, ze względu na to, czy wartości ANSI NULL są WŁĄCZONE czy WYŁĄCZONE, ale zdumiewa to, dlaczego proste "== null" w rzeczywistości będzie działać tak, jak można się spodziewać.
źródło
Osobiście wolę:
nad
ponieważ zapobiega powtórzeniom - choć nie jest to matematycznie dokładne, ale pasuje do większości przypadków.
źródło
Nie jestem w stanie skomentować posta divegi, ale spośród różnych przedstawionych tutaj rozwiązań rozwiązanie divega generuje najlepszy SQL. Zarówno pod względem wydajności, jak i długości. Właśnie sprawdziłem z SQL Server Profiler i spojrzałem na plan wykonania (z "SET STATISTICS PROFILE ON").
źródło
Niestety w Entity Framework 5 DbContext problem nadal nie został rozwiązany.
Użyłem tego obejścia (działa z MSSQL 2012, ale ustawienie ANSI NULLS może być przestarzałe w każdej przyszłej wersji MSSQL).
Należy zauważyć, że jest to brudne obejście, ale można je bardzo szybko wdrożyć i działa dla wszystkich zapytań.
źródło
Jeśli wolisz używać składni metody (lambda) tak jak ja, możesz zrobić to samo:
źródło
użyć tego
źródło