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);
}
ここで必要なことを行うには、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
ただし、短いバージョン:括弧を削除します。
空のリストを処理できるようにすることに興味がある場合は、重要な注意事項を追加します。別名、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を初めて使用することもあり、これを解決するのに少し時間がかかりすぎました。