ダッパパラメータが機能しない

c# dapper

質問

Dapper ormを次の簡単なクエリで使用しようとしています。

var sqlString = new StringBuilder();
sqlString.Append("select a.acct AccountNumber,");
sqlString.Append("       b.first_name FirstName,");
sqlString.Append("       b.last_name LastName,");
sqlString.Append("       a.rr RrNumber,");
sqlString.Append("       c.addr1 AddressLine1,");
sqlString.Append("       c.addr2 AddressLine2,");
sqlString.Append("       c.addr3 AddressLine3,");
sqlString.Append("       c.addr4 AddressLine4,");
sqlString.Append("       c.addr5 AddressLine5,");
sqlString.Append("       c.addr6 AddressLine6,");
sqlString.Append("       c.addr7 AddressLine7,");
sqlString.Append("       c.addr8 AddressLine8 ");
sqlString.Append("from (pub.mfclac as a left join pub.mfcl as b on a.client=b.client) ");
sqlString.Append("left join pub.mfclad as c on a.client=c.client ");
sqlString.Append("where a.acct = '@ZYX'");

var connection = new OdbcConnection(_connectionString);

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

しかし、存在することがわかっているaccountNumberでこれを実行すると、dapperは何も返しません。そこで、引用符を削除して、パラメータが実際にアカウント番号に置き換えられていることを確認しようとしましたが、サーバーから返されるエラーは "@ ZYX"の前後に構文エラーがあることを示しています。これは、dapperが指定された値でパラメータを置き換えていないことを意味します。これがなぜ起こっているのか?限られたドキュメンテーションから、これは「うまくいく」べきです。


Edit1

これを動作させることができませんでした。 string.formatを使用して回避策としてパラメータを挿入します。

受け入れられた回答

ここには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
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow