.net - query - net dapper




SELECT*FROM X WHERE ID IN(...) mit Dapper ORM (6)

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 }});

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?


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.

  1. Erstellen Sie Ihren TVP-Typ in MSSQL:

    CREATE TYPE [dbo].[MyTVP] AS TABLE([ProviderId] [int] NOT NULL)
    
  2. Erstellen Sie eine DataTable mit den gleichen Spalten wie die TVP und füllen Sie sie mit Werten

    var tvpTable = new DataTable();
    tvpTable.Columns.Add(new DataColumn("ProviderId", typeof(int)));
    // fill the data table however you wish
    
  3. Ändern Sie Ihre Dapper-Abfrage, um einen INNER JOIN in der TVP-Tabelle INNER JOIN :

    var query = @"SELECT * FROM Providers P
        INNER JOIN @tvp t ON p.ProviderId = t.ProviderId";
    
  4. Ü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.





dapper