Dapperはスカラー変数を宣言する必要があります

c# dapper parameterized-query sql

質問

Dapperでparamaterizedクエリを使用しようとすると問題が発生します。同様の問題を抱えている他の多くのユーザーが見つかりましたが、問題を解決できませんでした。

コード

    public User GetUser(int employeeId)
    {
        var args = new
        {
            EmployeeId = employeeId
        };

        const string sql = @"
                    select 
                        first_name 'FirstName', 
                        last_name 'LastName'
                    from 
                        users 
                    where 
                        employee_id = @EmployeeId 
                ";

        using (var con = MakeConnection())
        {
            var r = con.Query<User>(sql, args);
            return r.FirstOrDefault();
        }
    }

エラー

A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in System.Data.dll

Additional information: ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Must declare the scalar variable "@EmployeeId".

私もDynamicParametersを使用して、代わりにそれを渡してみましたが、どちらも動作していません

var p = new DynamicParameters();
p.Add("@EmployeeId", employeeId); // I have also tried without the @
//...
var r = con.Query<User>(sql,p);

受け入れられた回答

ここには2つの問題があります。最初に(あなたの質問ではこれを書き留めていますが)SQLルールの下にwhere a.acct = '@ZYX'はパラメータを使用しません。 @記号を含むリテラル文字列と一致するように見えます。 SQL Serverの場合(下記の注を参照)、正しい使用法はwhere a.acct = @ZYXです。

しかしながら! OdbcConnectionを使用しているOdbcConnection 、名前付きパラメーターは適用されません 。実際にSQL Serverのようなものに接続する場合は、ODBCよりも優れた機能とパフォーマンスを備えた純粋なADO.NETクライアントを使用することを強くお勧めします。ただし、ODBCが唯一のオプションである場合、 名前付きパラメーターは使用されません 。数日前まで、これは大きな問題を抱えていましたが、 OleDbを使用してDapperでクエリパラメータを渡すと、コードは(まだNuGetパッケージではなく)ODBCをサポートするようになりました。ソースからビルドする場合(または次のリリースを待つ場合)は、次のものを使用できるはずです。

...
where a.acct = ?

あなたのコマンドで、そして:

var result = connection.Query(sqlString.ToString(),
new {
    anythingYouLike = accountNumber
});

名前( anythingYouLike )はODBCでは使われていないので、 好きなようにすることができます。より複雑なシナリオでは、たとえば次のようになります。

.Execute(sql, new { id = 123, name = "abc", when = DateTime.Now });

dapperは、匿名型がどのように実装されていて、元の順序を理解して正しい順序( idnamewhen )でコマンドに追加するかについての知識を使用します。

1つの最終的な観察:

これは、dapperが指定された値でパラメータを置き換えていないことを意味します。

Dapper 、パラメータを指定された値で置き換えることはありません 。これは、単にsqlをパラメータ化する正しい方法ではありません。通常、パラメータは別々に送信され、次のことを保証します。

  • SQLインジェクションのリスクはありません
  • 最大のクエリプランの再利用
  • 書式設定の問題はありません

ADO.NET / ODBCプロバイダの中には、理論的には 、内部的に置き換えを行うことを選択できるものもありますが、これはdapperとは別です。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ