私は次のコードを持っています:
static void Main(string[] args){
string sql= "SELECT * FROM Posts WHERE 1=1 ";
SqlParameter[] @params= SetDynamicParameter(ref sql, "Param=Value", "Param2=Value2", "ParamN=ValueN");
IDbConnection connection = new SqlConnection(connectionString);
IEnumerable<Posts> en = connection.Query<Posts>(sql,param:@params);
Console.ReadKey(true);
}
static SqlParameter[] SetDynamicParameter(ref string sql,params string[] sarr) {
string condition = string.Empty;
List<SqlParameter> list = new List<SqlParameter>();
foreach (var item in sarr)
{
condition += " AND "+item.Split('=')[0] + "=@" + item.Split('=')[0];
list.Add(new SqlParameter("@" + item.Split('=')[0], item.Split('=')[1]));
}
sql += condition;
return list.ToArray() ;
}
出力エラー:このコンテキストでは、パラメーターの列挙可能なシーケンス(配列、リストなど)は許可されていません。
どうすればよいですか?同等の解決策はありますか?
SqlParameter
配列の代わりにDapper.DynamicParameters
を使用してみてください。
var parameters = new DynamicParameters();
parameters.Add("@ParameterName", parameterValue);
Query<>
の代わりにExecuteNonQuery
を使用すると、この例外は発生しなくなります。ただし、OracleでQueryを使用すると、別の問題が発生します。
この問題に対する私の解決策は、中間テーブルを使用することでした。私はOracleを使用していました。 Oracleには、sys
スキーマの下にある「dual」と呼ばれる特別なテーブルがあります。このテーブルは私にインスピレーションを与え、ユーザーのスキーマの下に別のテーブルを作成しました。
CREATE TABLE USER_SCHEMA.DUAL2
(
DUMMY VARCHAR2(1000 BYTE)
)
NOCOMPRESS
NOCACHE
NOPARALLEL;
必要に応じて長さを伸ばすことができます。テーブルにいくつかの助成金を与えました。次に、クエリをselectからselectステートメントの挿入に変更しました。
INSERT INTO USER_SCHEMA.DUAL2
(SELECT ID
FROM ANOTHER_SCHEMA.SOME_TABLE
WHERE SOME_FLAG = 'M' AND NO IN :NO)
これは、ADO.NETがExecuteNonQuery
から結果を返すことができないためです。デフォルトでは、SELECT
クエリを実行しますが、クエリごとに-1を返します。 INSERT
クエリを提供して、SELECT
をシミュレートしています。これは結果を返します。
var parameters = noSplit.Select(x => new { NO = x, SOME_FLAG = flag }).ToList();
var queryResult = dbConnection.Execute(insertSelectQuery, parameters, transactionIfExists);
if (queryResult != parameters.Count)
{
throw new Exception("Can not find some no");
}
私はこれがあなたにとってちょっと遅いことを知っています、しかし多分それは他の誰かを助けるかもしれません:)
あなたはこのようにそれを行うことができます:
_public class MySqlDataAccess
{
string _connectionString = "{your connection string}";
public async Task<IEnumerable<CustomerDto>> GetListAsync(IList<Guid> customers)
{
const string query = @"
SELECT TOP 100 Id,
Name
FROM Customers
WHERE Id IN @CustomerIdList
";
using (var c = new SqlConnection(_connectionString))
{
return await c.QueryAsync<CustomerDto>(query, new { CustomerIdList = customers.ToArray() });
}
}
}
_
_WHERE Id IN @CustomerIdList
_を実行してから、配列を直接渡す代わりに、new { CustomerIdList = customers.ToArray() }
のように配列から匿名型を渡します。
それが役に立てば幸い!