.net - query - net dapper
SELECT*FROM X WHERE ID IN(...) mit Dapper ORM (6)
Was ist der beste Weg, um eine Abfrage mit IN-Klausel mit Dapper ORM zu schreiben, wenn die Liste der Werte für die IN-Klausel aus Geschäftslogik kommt? Nehmen wir zum Beispiel an, ich habe eine Frage:
SELECT *
FROM SomeTable
WHERE id IN (commaSeparatedListOfIDs)
Die commaSeparatedListOfIDs
wird aus der Geschäftslogik übergeben und kann eine beliebige Art von IEnumerable(of Integer)
. Wie würde ich in diesem Fall eine Abfrage erstellen? Muss ich tun, was ich bisher gemacht habe, was im Grunde String-Verkettung ist oder gibt es eine Art von fortgeschrittener Parameter-Mapping-Technik, die mir nicht bekannt ist?
Dapper unterstützt dies direkt. Beispielsweise...
string sql = "SELECT * FROM SomeTable WHERE id IN @ids"
var results = conn.Query(sql, new { ids = new[] { 1, 2, 3, 4, 5 }});
Direkt von der GitHub Projekt Homepage :
Dapper ermöglicht es Ihnen, IEnumerable zu übergeben und Ihre Abfrage automatisch zu parametrisieren.
connection.Query<int>(
@"select *
from (select 1 as Id union all select 2 union all select 3) as X
where Id in @Ids",
new { Ids = new int[] { 1, 2, 3 });
Wird übersetzt zu:
select *
from (select 1 as Id union all select 2 union all select 3) as X
where Id in (@Ids1, @Ids2, @Ids3)
// @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3
Ich weiß, dass dies keine neuere Frage ist, es ist nicht notwendig, ()
in der Whel-Klausel von Sql, die wir normalerweise machen, hinzuzufügen, weil Dapper das automatisch für Sie tut. Hier ist die Syntax, die jemandem helfen kann.
const string SQL = "SELECT IntegerColumn, StringColumn FROM SomeTable WHERE IntegerColumn IN @EnumeratedList";
var conditions = new { listOfIntegers };
var results = connection.Query(SQL, conditions);
In meinem Fall habe ich das verwendet:
var query = "select * from table where Id IN @Ids";
var result = conn.Query<MyEntity>(query, new { Ids = ids });
meine Variable "ids" in der zweiten Zeile ist ein IEnumerable von Strings, auch sie können ganze Zahlen sein, denke ich.
Stellen Sie außerdem sicher, dass Sie Ihre Abfragezeichenfolge nicht wie folgt umschließen:
SELECT Name from [USER] WHERE [UserId] in (@ids)
Ich hatte dies verursacht einen SQL-Syntax-Fehler mit Dapper 1.50.2, behoben durch Entfernen von Klammern
SELECT Name from [USER] WHERE [UserId] in @ids
Wenn Ihre IN
Klausel zu groß für MSSQL ist, können Sie einen TableValueParameter mit Dapper ziemlich einfach verwenden.
Erstellen Sie Ihren TVP-Typ in MSSQL:
CREATE TYPE [dbo].[MyTVP] AS TABLE([ProviderId] [int] NOT NULL)
Erstellen Sie eine
DataTable
mit den gleichen Spalten wie die TVP und füllen Sie sie mit Wertenvar tvpTable = new DataTable(); tvpTable.Columns.Add(new DataColumn("ProviderId", typeof(int))); // fill the data table however you wish
Ändern Sie Ihre Dapper-Abfrage, um einen
INNER JOIN
in der TVP-TabelleINNER JOIN
:var query = @"SELECT * FROM Providers P INNER JOIN @tvp t ON p.ProviderId = t.ProviderId";
Übergeben Sie die DataTable in Ihrem Dapper-Query-Aufruf
sqlConn.Query(query, new {tvp = tvpTable.AsTableValuedParameter("dbo.MyTVP")});
Dies funktioniert auch fantastisch, wenn Sie eine Massenaktualisierung von mehreren Spalten durchführen möchten - einfach ein TVP erstellen und ein UPDATE
mit einer inneren Verbindung zum TVP durchführen.