1

POCO モデルで外部キーと子コレクションを公開しないと、Dapper で問題が発生します。2 つのエンティティを使用した簡単な例を見てみましょう。

Bike (Id, ModelName)
Tire (Id, Tread)

データベースでは、各 Tire に Bike への外部キーがあります。しかし、私のモデルはそうではありません。データベースから、この構造をDictionary<Bike, IEnumerable<Tire>>. 各バイク (固有) には 2 つのタイヤがあります。

次のクエリを使用して、この 1 対多の関係を選択できます。

SELECT b.Id, b.ModelName, t.Id, t.Tread
FROM Bike b
JOIN Tire t ON b.Id = t.bike_id

Dapper を使用してそれをマッピングするために、次のことを行いました。

var dbResult = connection.Query<Bike, Tire, KeyValuePair<Bike, Tire>>("sql-query-above",
(a, s) => new KeyValuePair<Bike, Tire>(a, s);
splitOn: "Id");

そして、LINQ を使用して、その結果を辞書に変換します。

Dictionary<Bike, IEnumerable<Tire>> dict = dbResult.GroupBy(g => g.Key, g => g.Value).ToDictionary(g => g.Key, g => g.AsEnumerable());

そして、データ構造を正しく返します。

Bike #1
 - Tire #1
 - Tire #2
Bike #2
 - Tire #3
 - Tire #4

しかし、これはこのデータ構造を具現化する最も効率的な方法でしょうか? 別の方法としては、ディクショナリを使用せず、外部キーと関係を公開する他のエンティティを作成し (例: Bike の Tires コレクションと Tire の FK)、ここで説明されているようなマッピング アプローチを使用します。しかし、多くの余分なクラスが発生するため、私のモデルではそれを避けたいと思います。しかし、パフォーマンスはどうですか?これは悪いですか、それとも同じですか?

4

1 に答える 1

0

私は Dapper を使用する専門家ではありませんが、あなたが経験しているような制限に遭遇しました。オブジェクトのプロパティの 1 つがタイヤのようなコレクションであるという同様の状況がありました。コレクションの内部型に拡張メソッドを設定する 2 つ目のクエリを作成する方が簡単であることがわかりました。

したがって、最初にすべてのバイクを取得してから、次のように拡張メソッドを呼び出してタイヤ データを取得することができます。

dict.WithTires();    

データベースへの 2 回目の呼び出しであることはわかっていますが、トレードオフは、タイヤの情報を毎回取得しなくても自転車をつかむことができることです。

また、辞書を使用するよりも優れている自転車クラスにタイヤ コレクションをプロパティとして追加することを検討することもできます。あなたがこのようなものを持っていたら:

public class Bike
{
    public int id { get; set; }
    public string modelName { get; set; }
    public IList<Tires> tires { get; set; }
}

public class Tires
{
    public int id { get; set; }
    public string tread { get; set; }
}

個々の自転車または自転車のコレクションのタイヤ データを取得するための拡張メソッドを簡単に作成できます。

Bike myBike = new Bike();
List<Bike> bikeCollection = new List<Bike>();

myBike.WithTires();
bikeCollection.WithTires();
于 2012-12-05T16:29:38.210 に答える