私が尋ねる最初の質問は、本当にこれを行う必要があるのかということです。型指定された DataSet デザイナーには、ストアド プロシージャと DataTable の間のマッピングを定義するためのツールが既に用意されています。DataSet を慎重に設計すると、すべての DataTable に Fill メソッドが既に用意されています。その車輪を再発明することは理にかなっていますか?
そうかもしれないと思います。そのマッピングを維持する方法があるのは本当に素晴らしいことですが、そのマッピングのすべてがコンパイル時に凍結されます。マッピングを変更する場合は、アセンブリを再構築する必要があります。また、型指定された DataSet 設計は、複数の結果セットを返すストアド プロシージャを処理しません。パラメーターと値を一般的にマップする場合は、リフレクションを使用して Fill メソッドから引数リストを取得する必要があります。これらの要因 (および私が考えていないその他の要因) を見ると、既存のツールを使用するのは適切ではない可能性があります。
その場合、あなたの目標は、一連のストアド プロシージャから DataSet に、実装の詳細について可能な限り知らないコードを入力できるようにすることだと思われます。つまり、これはメタデータによって駆動されるプロセスです。メタデータによって駆動されるプロセスがある場合、長期的に最も重要なことは、プロセスが使用するメタデータをいかに簡単に維持できるかということです。コードが機能するようになると、おそらくあまり触れないでしょう。ただし、メタデータを常に調整する必要があります。
その観点から問題を見ると、最初にすべきことは、型指定された DataSet を設計してメタデータを含めることです。これにより、他の方法では把握しなければならない多くのことがわかります。
- 持続形式
- バインドされた UI を構築する簡単な方法
- データベースにメタデータを永続化するための同じように簡単な方法は、その道を進むことにした場合です。
- データをナビゲートするためのオブジェクト モデル。
この DataSet には、入力できる各型指定された DataSet の Type をキーとする DataSetType テーブルがあります。子の StoredProcedures テーブルがあり、呼び出される各 SP の行があります。これには、Parameter と DataTableType の 2 つの子テーブルがあります。SP が返すと予想される結果セットごとに、序数順に並べられた 1 つの DataTableType 行があります。DataTableType テーブルには、子 ColumnMapping テーブルがあります。結果セットの列とデータを入力しているテーブルの列の間のマッピングを維持するのは、そのテーブルです。
すべての DataRelations がネストされていること、およびリレーションに合理的な名前を付けていることを確認してください。(私は好きFK_childtablename_parenttablename
です。)
これがあれば、クラスの設計は非常に簡単になります。このクラスには、メタデータ DataSet、接続などへの参照があり、次のシグネチャを持つメソッドを公開します。
public void FillDataSet(DataSet targetDs, Dictionary<string, Dictionary<string, KeyValuePair<string, string>> parameterMap);
まず、targetDs の Type を使用して最上位の DataSetType 行を見つけます。次に、すべてのプライベート メソッドが、DataTable.GetChildRows() によって返された DataRows のリストを反復処理します。また、クラスの設計に 1 つまたは 2 つのイベントを追加して、操作を実行するときにイベントを発生させて、呼び出し元のアプリケーションに進行状況を知らせることができます。
おそらく、この設計をリファクタリングすることを期待する最初の場所は、充填プロセスをよりきめ細かく制御できるようにすることです。たとえば、設計どおり、型指定された DataSet ごとに SP のセットは 1 つだけです。DataSet のサブセットのみを入力したい場合はどうすればよいですか? 設計どおり、できません。ただし、DataSetType テーブルの主キーを簡単に 2 つの部分で構成し、その部分を DataSet タイプと文字列キー (SPSetName や OperationName などの名前) にして、キーの 2 番目の部分を FillDataSet 引数リストに追加することができます。 .