Comment utiliser "Where In" dans Dapper

.net c# dapper orm sql

Question

J'ai essayé sans succès pendant un certain temps d'utiliser un IEnumerable<string> avec une WHERE IN dans Dapper.

Dans la documentation, il est dit que IEnumerable<int> est pris en charge pour une utilisation dans WHERE IN mais je ne peux même pas le faire fonctionner.

Dapper allow you to pass in IEnumerable<int> and will automatically parameterize your query.

Le message d'erreur que je continue à recevoir est une erreur de syntaxe SQL. Incorrect syntax near ','.

J'ai mis en place un code de test qui, je l'espère, démontrera ce que j'essaie de réaliser.


string connString = "Server=*.*.*.*;Database=*;User Id=*;Password=*;";

string sqlStringIn = @"SELECT StringText FROM 
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data
                WHERE StringId IN (@str)";

string sqlIntegerIn = @"SELECT StringText FROM 
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data
                WHERE ID IN (@integer)";


using (SqlConnection conn = new SqlConnection(connString))
{
    conn.Open();

    List<int> integers = new List<int>{ 1, 2, 3 };
    List<string> strings = new List<string> { "A", "B", "C" };

    var parameters = new {str = strings, integer = integers };

    //fails here
    IEnumerable<string> intTest = conn.Query<string>(sqlIntegerIn, parameters, commandType: System.Data.CommandType.Text);

    //and here
    IEnumerable<string> stringTest = conn.Query<string>(sqlStringIn, parameters, commandType: System.Data.CommandType.Text);

}

Réponse acceptée

Pour ce faire ce qui est nécessaire ici, les besoins dapper pour modifier le SQL à la volée - il doit être vraiment sûr qu'il est en train de faire la bonne chose. La syntaxe SQL valide inclut des parenthèses:

WHERE StringId IN (@str)

Pour y remédier, la syntaxe voodoo dapper omet la parenthèse:

WHERE StringId IN @str

S'il le détecte, il recherche un paramètre appelé str et le développe en un des éléments suivants:

WHERE 1=0 -- if no values
WHERE StringId = @str -- if exactly one value
WHERE StringId IN (@str0, @str1, ...) -- if more than one value

Mais version courte: supprimer la parenthèse.


Réponse populaire

Je veux ajouter une note importante si vous êtes intéressé à pouvoir gérer une liste vide, aka rendre la clause IN optional . Je l'ai fait en ajoutant une propriété pour contenir le compte tel que public int InClauseCount => InClauseList?.Length ?? 0;

Ensuite, utilisez le décompte dans le sql comme ceci ...

Select field1, field2
from Table1
where (some condition)
AND (@InClauseCount = 0 OR field1 IN @InClauseList)

J'espère que cela peut aider quelqu'un là-bas. J'ai passé un peu trop de temps à essayer de résoudre ce problème, en partie parce que je suis nouveau sur Dapper.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi