Czytałem, że nierozsądne jest używanie ToUpper i ToLower do porównywania ciągów bez uwzględniania wielkości liter, ale nie widzę alternatywy, jeśli chodzi o LINQ-to-SQL. Argumenty ignoreCase i CompareOptions String.Compare są ignorowane przez LINQ-to-SQL (jeśli używasz bazy danych z uwzględnieniem wielkości liter, otrzymasz porównanie z rozróżnianiem wielkości liter, nawet jeśli poprosisz o porównanie bez uwzględniania wielkości liter). Czy ToLower lub ToUpper jest tutaj najlepszą opcją? Czy jeden jest lepszy od drugiego? Myślałem, że gdzieś czytałem, że ToUpper jest lepsze, ale nie wiem, czy to dotyczy tutaj. (Robię wiele recenzji kodu i wszyscy używają ToLower.)
Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0
Przekłada się to na zapytanie SQL, które po prostu porównuje parametr row.Name z wartością „test” i nie zwraca wartości „Test” ani „TEST” w bazie danych uwzględniającej wielkość liter.
LINQQuery.Contains("VaLuE", StringComparer.CurrentCultureIgnoreCase)
iLINQQuery.Except(new string[]{"A VaLUE","AnOTher VaLUE"}, StringComparer.CurrentCultureIgnoreCase)
. Wahoo!Odpowiedzi:
Jak powiedziałeś, istnieją pewne ważne różnice między ToUpper i ToLower, a tylko jedna jest niezawodna, gdy próbujesz sprawdzić równość bez rozróżniania wielkości liter.
Najlepszym sposobem sprawdzenia równości bez uwzględniania wielkości liter byłoby :
UWAGA, JEDNAK, że to nie działa w tym przypadku! Dlatego utknęliśmy z
ToUpper
lubToLower
.Zwróć uwagę na porządkową IgnoreCase, aby była bezpieczna. Ale dokładnie rodzaj sprawdzania (nie) wrażliwego na wielkość liter, którego używasz, zależy od twoich celów. Ale ogólnie rzecz biorąc, użyj Equals do sprawdzania równości i porównaj podczas sortowania, a następnie wybierz odpowiedni StringComparison dla zadania.
Michael Kaplan (uznany autorytet w dziedzinie kultury i postępowania z postaciami, takiego jak ten), ma odpowiednie posty w ToUpper vs.ToLower:
Mówi „String.ToUpper - użyj ToUpper zamiast ToLower i określ InvariantCulture, aby wybrać reguły wielkości liter systemu operacyjnego ”
źródło
Użyłem
System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test")
w moim zapytaniu.Wykonuje porównanie bez rozróżniania wielkości liter.
źródło
SqlClient
.Wypróbowałem to używając wyrażenia Lambda i zadziałało.
List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );
źródło
List<>
, co oznacza, że porównanie odbywa się w pamięci (kod C #), a nieIQueryable
(lubObjectQuery
), które wykonałoby porównanie w bazie danych .Jeśli przekażesz ciąg, który nie rozróżnia wielkości liter do LINQ-to-SQL, zostanie on przekazany do kodu SQL bez zmian, a porównanie nastąpi w bazie danych. Jeśli chcesz wykonywać porównania ciągów bez uwzględniania wielkości liter w bazie danych, wszystko, co musisz zrobić, to utworzyć wyrażenie lambda, które wykonuje porównanie, a dostawca LINQ-to-SQL przetłumaczy to wyrażenie na zapytanie SQL z nienaruszonym ciągiem.
Na przykład to zapytanie LINQ:
zostaje przetłumaczony na następujący kod SQL przez dostawcę LINQ-to-SQL:
Jak widać, parametr string zostanie porównany w SQL, co oznacza, że wszystko powinno działać tak, jak byś tego oczekiwał.
źródło
Aby wykonywać zapytania Linq to Sql z rozróżnianiem wielkości liter, należy zadeklarować w polach typu „string”, aby uwzględniana była wielkość liter, określając typ danych serwera za pomocą jednego z poniższych;
lub
Uwaga: „CS” w powyższych typach sortowania oznacza „Z uwzględnieniem wielkości liter”.
Można to wprowadzić w polu „Typ danych serwera” podczas przeglądania właściwości w programie Visual Studio DBML Designer.
Więcej informacji można znaleźć pod adresem http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html
źródło
źródło
U mnie działa następujące dwuetapowe podejście (VS2010, ASP.NET MVC3, SQL Server 2008, Linq to SQL):
źródło
!= -1
ponieważIndexOf
„zwraca wartość -1, jeśli znak lub ciąg nie zostanie znaleziony”Czasami wartość przechowywana w bazie danych może zawierać spacje, więc uruchomienie tego może się nie powieść
Rozwiązaniem tego problemu jest usunięcie miejsca, a następnie przekonwertowanie jego obudowy, a następnie wybranie w ten sposób
Uwaga w tym przypadku
nazwa_własna to wartość pasująca do wartości bazy danych
UsersTBs to klasa
tytuł to kolumna Baza danych
źródło
Pamiętaj, że istnieje różnica między tym, czy zapytanie działa, a wydajnością ! Instrukcja LINQ jest konwertowana na T-SQL, gdy celem instrukcji jest SQL Server, więc musisz pomyśleć o T-SQL, który zostanie utworzony.
Użycie String.Equals najprawdopodobniej (zgaduję) spowoduje przywrócenie wszystkich wierszy z SQL Server, a następnie wykonanie porównania w .NET, ponieważ jest to wyrażenie .NET, którego nie można przetłumaczyć na T-SQL.
Innymi słowy, użycie wyrażenia zwiększy dostęp do danych i usunie możliwość korzystania z indeksów. Sprawdzi się na małych stolikach i nie zauważysz różnicy. Na dużym stole mogłaby się bardzo źle spisać.
To jeden z problemów występujących w LINQ; ludzie nie myślą już o tym, jak spełnią się wypowiedziane przez nich wypowiedzi.
W tym przypadku nie ma sposobu na zrobienie tego, co chcesz, bez użycia wyrażenia - nawet w T-SQL. Dlatego możesz nie być w stanie zrobić tego wydajniej. Nawet odpowiedź T-SQL podana powyżej (przy użyciu zmiennych z sortowaniem) najprawdopodobniej spowoduje zignorowanie indeksów, ale jeśli jest to duża tabela, warto uruchomić instrukcję i spojrzeć na plan wykonania, aby sprawdzić, czy został użyty indeks .
źródło