Jaki jest najlepszy sposób na napisanie zapytania z klauzulą IN za pomocą Dapper ORM, gdy lista wartości dla klauzuli IN pochodzi z logiki biznesowej? Powiedzmy na przykład, że mam zapytanie:
SELECT *
FROM SomeTable
WHERE id IN (commaSeparatedListOfIDs)
commaSeparatedListOfIDs
Przekazywana jest z logiką biznesową i może być dowolnego typu IEnumerable(of Integer)
. Jak skonstruowałbym zapytanie w tym przypadku? Czy muszę robić to, co do tej pory robiłem, a mianowicie konkatenację łańcuchów znaków, czy też istnieje zaawansowana technika mapowania parametrów, o której nie wiem?
IN
klauzuli.Bezpośrednio ze strony głównej projektu GitHub :
Zostanie przetłumaczony na:
źródło
Jeśli twoja
IN
klauzula jest zbyt duża, aby ją obsłużyć MSSQL, możesz dość łatwo użyć TableValueParameter z Dapper.Utwórz swój typ TVP w MSSQL:
Utwórz
DataTable
z tymi samymi kolumnami co TVP i wypełnij go wartościamiZmodyfikuj zapytanie Dapper, aby wykonać
INNER JOIN
na tabeli TVP:Przekaż tabelę danych w wywołaniu zapytania Dapper
Działa to również fantastycznie, gdy chcesz dokonać masowej aktualizacji wielu kolumn - po prostu zbuduj TVP i wykonaj
UPDATE
wewnętrzne połączenie z TVP.źródło
ProviderId
naMyTVP
byćPRIMARY KEY CLUSTERED
, jak to tylko rozwiązać problem z wydajnością dla nas (wartości Mijaliśmy nie zawierał żadnych duplikatów).Oto prawdopodobnie najszybszy sposób na zapytanie dużej liczby wierszy za pomocą Dappera przy użyciu listy identyfikatorów. Obiecuję ci, że jest to szybsze niż prawie jakikolwiek inny sposób, w jaki możesz myśleć (z możliwym wyjątkiem użycia TVP podanego w innej odpowiedzi, a którego nie przetestowałem, ale podejrzewam, że może być wolniejszy, ponieważ nadal musisz się wypełnić TVP). Jest planetami szybszymi od Dappera przy użyciu
IN
składni i wszechświatów szybciej niż Entity Framework wiersz po rzędzie. I nawet kontynenty są szybsze niż przekazywanie listyVALUES
lubUNION ALL SELECT
przedmiotów. Można go łatwo rozszerzyć, aby używał klucza wielokolumnowego, wystarczy dodać dodatkowe kolumny doDataTable
, tabeli tymczasowej i warunków łączenia.Pamiętaj, że musisz trochę dowiedzieć się o wkładkach luzem. Istnieją opcje dotyczące wyzwalania wyzwalaczy (domyślnie nie), przestrzeganie ograniczeń, blokowanie tabeli, zezwalanie na jednoczesne wstawianie itd.
źródło
DataTable
Jest wymagana dla wkładki luzem. Jak pan wstawić do tabeli temp 50.000 wartości?Upewnij się również, że nie zawijasz nawiasów wokół ciągu zapytania w taki sposób:
Miałem tę przyczynę błędu składni SQL przy użyciu Dappera 1.50.2, naprawionego przez usunięcie nawiasów
źródło
Nie jest konieczne dodawanie
()
klauzuli WHERE, tak jak w zwykłym SQL. Ponieważ Dapper robi to dla nas automatycznie. Otosyntax
:źródło
Przykład dla postgres:
źródło
W moim przypadku użyłem tego:
moje zmienne „ids” w drugim wierszu są IEnumerable ciągów, również mogą to być liczby całkowite.
źródło
List<string>
?Z mojego doświadczenia wynika, że najbardziej przyjaznym sposobem radzenia sobie z tym jest posiadanie funkcji, która przekształca ciąg znaków w tabelę wartości.
W Internecie dostępnych jest wiele funkcji splittera, z łatwością znajdziesz jedną dla siebie, niezależnie od smaku SQL.
Możesz wtedy zrobić ...
Lub
(Lub podobne)
źródło