TableAdapterManager って?

こんにちは、こだかです。

ちょっと前の事です。
型付データセットを作成して、適当にコーディングをしていたときに気がついたのですが、
「まず、Dataset を作って、次に TableAdapter を作って・・・」
「っん?」

TableAdapeterManager なるものが見えます。
まぁしかし、特に気にせずコーディングしていました。
で、今度は、データバインドを行うプログラムを作成してみたところ、

        private void jobsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();
            this.jobsBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.pubsDataSet);
        }

といった形で、暗黙的に追加されるコードにも使われているんですね。
よく見ると、データコンポーネントの中にもいたりします。

こうなってくると、そろそろ無視できませんので、軽く調べてみます。(ようやくですね・・・)
どうも Visual Studio 2008 より、型付データセットを作成したタイミングで、同時に出来るようです。
DataSet.Designer を確認してみると、TableAdapterManagerは、内部に TableAdaper の参照をもっていて、
例えば前述の UpdateAll のソースですが、複数の TableAdaper の更新処理をトランザクション配下で実行してくれています。

つまり、こんなメリットがあるということです。
例として、親子関係のある2つのテーブルに対して、データの連鎖削除を考えてみます。
親を削除した場合、関連する子供も同時に削除するといった場合です。

まず、以下のように2つのDatatableからデータを削除して、

            //employeeテーブルから該当レコードを削除
            DataRow[] rws = jobsDataSet.employee.Select("job_id = '" + this.job_idTextBox.Text + "'");
            foreach (DataRow rw in rws)
            {
               rw.Delete();
            }

            //jobsテーブルからカレントレコードを削除
            jobsBindingSource.RemoveCurrent();
           
次にこれまで(Visual Studio 2005まで)の書き方では、以下の様に、2つの TableAdaper を使用して Update 処理を行っていたと思います。
その際、トランザクションを掛けておくのが一般的でしょう。

            try
            {
                using (TransactionScope tx = new TransactionScope())
                {
                    employeeTableAdapter.Update(this.jobsDataSet.employee);
                    jobsTableAdapter.Update(this.jobsDataSet.jobs);
                    tx.Complete();
                }
            }
            catch
            {
                //トランザクションはロールバックされる
            }

しかし、この処理(TableAdaperの部分)が、TableAdapterManagerを使用すると、
以下の1行で、済んでしまうわけですね。

            this.tableAdapterManager.UpdateAll(this.jobsDataSet);

これが前述の、データバインドの暗黙的に追加されるコードになっている訳です。

ちなみに FormのDesigner を確認すると、TableAdaper を複数使用する場合、
以下のような記述が書かれている為、事前に TableAdapterManager に TableAdaper を登録することなく、
いきなり UpdateAll を実行できます。

            // tableAdapterManager
            //
            this.tableAdapterManager.BackupDataSetBeforeUpdate = false;
            this.tableAdapterManager.employeeTableAdapter = this.employeeTableAdapter;
            this.tableAdapterManager.jobsTableAdapter = this.jobsTableAdapter;
            this.tableAdapterManager.UpdateOrder = Demo.pubsDataSetTableAdapters.TableAdapterManager.UpdateOrderOption.InsertUpdateDelete;

って、みなさんご存じでした?
私だけ?

こだかたろう