web-dev-qa-db-ja.com

Dapperで「WhereIn」を使用するにはどうすればよいですか

DapperでIEnumerable<string>句をWHERE IN句とともに使用しようとしてしばらく失敗しました。

ドキュメントには、IEnumerable<int>WHERE INでの使用がサポートされていると記載されていますが、それを機能させることすらできません。

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

私が受け取り続けるエラーメッセージは、SQL構文エラーです。 Incorrect syntax near ','.

私が達成しようとしていることを実証することを願っているいくつかのテストコードをまとめました。


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

}
24
Sam

ここで必要なことを行うには、dapperはSQLをオンザフライで変更する必要があります。したがって、正しいことを実行していることを本当に確認する必要があります。通常の有効なSQL構文には、括弧が含まれています。

WHERE StringId IN (@str)

これを明確にするために、voodoo dapper構文省略括弧:

WHERE StringId IN @str

これを検出すると、strというパラメータを探し、次のいずれかに展開します。

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

ただし、短いバージョン:括弧を削除します。

48
Marc Gravell

空のリストを処理できるようにすることに興味がある場合は、重要な注意事項を追加します。別名、IN句をoptionalにします。これを行うには、public int InClauseCount => InClauseList?.Length ?? 0;などのカウントを含むプロパティを追加しました。

次に、次のようにSQL内のカウントを使用します...

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

これが誰かの助けになることを願っています。 Dapperを初めて使用することもあり、これを解決するのに少し時間がかかりすぎました。

3
user1856792