1

私のアプリケーションは以下のエンティティモデルであり、Dapper を使用しています

public class Goal
{
    public string Text { get; set; }
    public List<SubGoal> SubGoals { get; set; }
}

public class SubGoal
{
    public string Text { get; set; }
    public List<Practise> Practices { get; set; }
    public List<Measure> Measures { get; set; }
}

以下のようなリポジトリがあります

public interface IGoalPlannerRepository
{
    IEnumerable<Goal> FindAll();
    Goal Get(int id);
    void Save(Goal goal);
}

以下の2つのシナリオに出くわしました

  1. データ (目標エンティティ) を取得する際に、階層内のすべての関連オブジェクトを取得する必要があります (すべてのサブ目標とプラクティスおよびメジャー)
  2. 目標が保存されると、すべての関連データを挿入および/または更新する必要があります

コレクションを「ループスルー」して大量のSQLクエリを作成する以外に、これらのシナリオを処理するためのより良い方法があることを提案してください。

4

1 に答える 1

4

Dapper を使用して SQL で大規模なバッチ データ更新を行う最善の方法は、複合クエリを使用することです。

次のように、1 つのクエリですべてのオブジェクトを複数の結果セットとして取得できます。

CREATE PROCEDURE get_GoalAndAllChildObjects
    @goal_id int
AS
SELECT * FROM goal WHERE goal_id = @goal_id
SELECT * FROM subgoals WHERE goal_id = @goal_id

次に、次のようにオブジェクトを取得する dapper 関数を記述します。

using (var multi = connection.QueryMultiple("get_GoalAndAllChildObjects", new {goal_id=m_goal_id})) {
    var goal = multi.Read<Goal>();
    var subgoals = multi.Read<SubGoal>();
}

次は、大量のデータをバッチで更新します。これは、テーブル パラメーターの挿入によって行います (これに関する記事をここに書きました: http://www.altdevblogaday.com/2012/05/16/sql-server-high-performance-inserts/ )。基本的に、挿入するデータの種類ごとに 1 つのテーブルを作成し、それらのテーブルをパラメーターとして受け取り、データベースに書き込むプロシージャを記述します。

これは非常に高性能であり、可能な限り最適化されています。また、コードはそれほど複雑ではありません。

ただし、質問する必要があります。「サブゴール」と他のすべてのオブジェクトを関連性を保つことに何か意味はありますか? 簡単な代替手段の 1 つは、ゴールとそのすべての子オブジェクトをテキストにシリアル化して含む XML または JSON ドキュメントを作成し、そのオブジェクトをファイル システムに保存することです。信じられないほど高性能で、非常にシンプルで、非常に拡張可能で、必要なコードはほとんどありません。唯一の欠点は、SQL ステートメントを記述してすべてのサブゴールをブラウズすることができないことです。考えてみてください - 考える価値があるかもしれません ;)

于 2012-08-21T05:10:03.020 に答える