LINQ自動生成型のDapperパラメータ化クエリ

c# dapper linq

質問

私は私の仕事でLINQとDapperの組み合わせを使用しています。パフォーマンス上の理由からLINQコードをDapperで置き換えています。私は、SQL ServerからVisual Studioのデータベースダイアグラムにドラッグアンドドロップすることによって作成されたLINQデータオブジェクトをたくさん持っています。

次の例では、私はすでにLINQオブジェクトをメモリに持っており、クエリのパラメータとしてDapperに渡したいと思います。例えば:

Animal animal = con.Query<Animal>(" select * " +
        " from animal " +
        " where animalid = @AnimalId " +
        " and animaltype = @AnimalType ",
        cagedAnimal).SingleOrDefault();

cagedAnimalには、ゲッターとセッターを持つパブリックプロパティAnimalIdとAnimalTypeが含まれています。

しかし、このコードを実行すると、次のエラーが発生します。

タイプ:SMDApp.Models.Animalは、dapperによってサポートされていません

次のコードは動作します:

Animal animal = con.Query<Animal>(" select * " +
            " from animal " +
            " where animalid = @AnimalId " +
            " and animaltype = @AnimalType ",
            new 
            { 
            AnimalId = cagedAnimal.AnimalId, 
            AnimalType = cagedAnimal.AnimalType 
            }
            ).SingleOrDefault();

既存のオブジェクトを使用する方が便利です(特に、オブジェクトの複数のプロパティをクエリのパラメータとして使用している場合)。誰も私の知ることができますなぜこれは、匿名のオブジェクトではなく、自動生成されたLINQオブジェクトの作品ですか?

ベン・ロビンソンの返答に応じて編集。

Marc Gravellの返答に応じて2回目を編集しました。

受け入れられた回答

短いバージョンはすでに動作するはずです。エラーに基づいて:

タイプ:SMDApp.Models.CagedAnimalは、dapperによってサポートされていません

私はあなたが実際に渡しているどちらかと結論new {cagedAnimal}の代わりcagedAnimalあるいは 、あなたのCagedAnimal性質がある( Parentおそらくを、?)そのものであることCagedAnimal 、そしてどのDapperのは理解できません。現在の挙動は、提供されたパラメータオブジェクトのすべてのパブリックプロパティに対してパラメータが追加さ 、データベースにいずれかのプロパティを送信する方法がわからない場合に不平を言います。値のメンバーだけの単純なPOCOがうまく動作することがわかります。

しかしながら!あなたのSQLを解析しようとすることはありません - 特に、提供されたクエリのパラメータをチェックしません。したがって、POCOアプローチを使用すると、クエリに不要なプロパティを追加することになります。

dapperを広範囲に使用しており、そのアプローチを使用しています。

 new { obj.Foo, obj.Bar, id, key = "something else" }

人気のある回答

Marc はこの問題を特に修正するための変更をコミットしました。

  1. プロパティをparamsに変換しようとする前に、簡単な検証を行います。たとえば、Dapperはこのケースではサーバーにパラメータを送信しません.cnn.Query( "select 1"、new {bla = 1})原因 "bla"が文字列に存在しません。この検証は、格納されたprocsに対してはスキップされます。

  2. むしろ隠されていたエラーは修正され、大幅に改善されました。

-

Dapperは、基礎となるSQL文の解析を実行しませんでした。例:

@"select * 
from animal
where animalid = @AnimalId"

@AnimalIdという単一のパラメータが含まれています。

それは複雑な原因を取得し、100%正しい場合は、エッジケースを処理する必要があります。EG: @AnimalIdを文字列select '@AnimalId' -- @AnimalId \* @AnimalId *\ ?正規表現は少しトリッキーになる、私はすべての端の場合を考えていない。たとえば、Oracleはparamsの前にa :を付けると、より複雑になります。

ダッパーは文字列のparamsについて何も知らなかったので、 すべてのパブリックプロパティをパラメータとして送信することに決めました。公共財産の一部はDbParametersにマップすることができないため、不平を言います。



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