データソースコントロールとの連携(その1)ではテーブルアダプターを使った ObjectDataSource の基本的な使い方について解説を行いました。今回はテーブルアダプターにカスタムロジックを追加してテーブルアダプターを拡張する方法について解説します。
● パーシャルを使ったテーブルアダプターの拡張
簡単に CRUD(Create Read Update Delete) のメソッドを作成できるテーブルアダプターですが、更新の前に更新内容をイベントログをはき出したいといったケースの場合標準のテーブルアダプターのみでは実現できません。
この場合、テーブルアダプターのパーシャルクラスにカスタムコードを記述してテーブルアダプターを拡張することができます。
○ パーシャルクラスと自動生成されたコード
その 1 で作成したテーブルアダプターやデータセットは XML の定義しかないにもかかわらず、.NET のクラスのように扱うことができます。これはどうしてでしょうか。実は ASP.NET では ASPX や DataSet などは、実行時に一度 Visual Basic や C# のソースファイルに変換されコンパイルされたものが実行されます。つまり DataSet や ASPX は実行時に作成される特殊なクラスと言うことができます。
この一時的に変換されたソースコードは次の場所に格納されています。
一時ファイルの格納先
%SystemRoot%\Microsoft.NET\Framework\[バージョン]\Temporary ASP.NET Files\[プロジェクト名]\[XXXXX]\[XXXXX]\Sources_App_Code
[ ] は .NET のバージョン、プロジェクト名などで変化します。
おそらくこれまでのサンプルを一度でも実行していれば上記フォルダ内に DataSet や ASPX のソースらしきものを見つけられると思います。このソースファイルのクラス定義を確認すると、パーシャルクラスとして定義されているのを確認できます。
パーシャルクラスは .NET Framework 2.0 で追加された機能で、1 つのクラスの定義を複数のファイルに分割して記述する機能です。DataSet の他にも、もっとも身近なところで ASPX のコードビハインドファイルが ASPX のパーシャルクラスになっているのを確認できると思います。
○ パーシャルクラスにカスタムロジックを追加
ObjectDataSource では、SqlDataSource に比べてデータアクセスレイヤーがあるおかげで、SQL だけでは行えない細かい動作を Visual Basic や C# で記述することができます。
例えば、Update の時に Windows のシステムログに更新があったことを記入したいとします。SqlDataSource ではちょっと難しい作業ですね。
データアクセスコンポーネントにテーブルアダプターを使用している場合、[リスト 0008]のようにテーブルアダプターのパーシャルクラスに拡張するコードを記述します。
Visual Studio でクラスファイルを追加し、次のコードを記述してください。
[リスト 0008] パーシャルクラスを使用したテーブルアダプターの拡張
Imports System.Diagnostics
Imports System.ComponentModel
Namespace DataSet1TableAdapters
Partial Public Class VSUGアカデミーTableAdapter
' 1
<DataObjectMethod(DataObjectMethodType.Update)> _
Public Function UpdateEx _
(ByVal タイトル As String, _
ByVal 開催日 As Date, _
ByVal セッション1 As String, _
ByVal セッション2 As String, _
ByVal Original_Id As String) As Integer
' 2
EventLog.WriteEntry( _
"VSUGLog", _
String.Format("検索:ID:{0}{1}", Original_Id, Environment.NewLine) & _
String.Format("更新パラメータ: タイトル:{0},開催日:{1},セッション1:{2},セッション2:{3}", _
タイトル, 開催日, セッション1, セッション2))
' 3
Return Update(タイトル, 開催日, セッション1, セッション2, Original_Id)
End Function
End Class
End Namespace
-------------------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Diagnostics;
namespace DataSet1TableAdapters
{
public partial class VSUGアカデミーTableAdapter
{
// 1
[DataObjectMethod(DataObjectMethodType.Update)]
public int UpdateEx(string タイトル,
DateTime 開催日,
string セッション1,
string セッション2,
string Original_Id)
{
// 2
EventLog.WriteEntry
("VSUGアカデミーTableAdapter",
String.Format("検索:ID:{0}{1}", Original_Id, Environment.NewLine) +
String.Format("更新パラメータ: タイトル:{0},開催日:{1},セッション1:{2},セッション2:{3}",
タイトル, 開催日, セッション1, セッション2));
// 3
return Update(タイトル, 開催日, セッション1, セッション2, Original_Id);
}
}
}
Visual Studio からデータセットを作成したときに同時に作成されるテーブルアダプターは、テーブル名 + TableAdapter という形式になります(この場合は VSUG アカデミーTableAdapter) 。プログラムの中に日本語名が出てくることに違和感がある人もいるかもしれませんが、下手にローマ字でテーブル名を考えたりおかしな英語を使うよりは母国語を使ってプログラミングを行った方が、読みやすいプログラムが可能であると筆者は考えています。特に業務に使用するテーブルやカラムには日本語特有の言い回しがあることが多く、できるだけ母国語で記述することをおすすめします。
1. 操作方法の指定
データアクセスコンポーネントで使用するメソッドには、DataObjectMethodAttribute の属性を指定して、そのメソッドが Fill, Select, Insert, Update, Delete のいずれの操作を行うかを指定します。この操作は必須ではなく単にテーブルアダプターを作成するウィザードに対し自分はどんな種類の操作を行うメソッドかを伝えるだけのものですが、クラス設計を行う際にはメソッドの意味を明確化するためにも何の処理を行うメソッドかを指定するようにすると、そのクラスを使う側がわかりやすい設計になると思います。
2. システムログの記述
Windows のアプリケーションログに今回更新する情報を書き込みます。
EventLog.WriteEntryは第一引数にイベントログのカテゴリ、第二引数にイベントのメッセージを設定できます。たとえば今回のログを記述した場合 Windows のイベントログには下図の用にログが記述されます。
【イベントログに出力されたログ】

3.更新
今回は、イベントログを記述するのが目的なので、Update メソッドは VSUGアカデミーTableAdapter が元々持っている Update メソッドを使用しています。
ここで独自の SQL を使った更新処理を行う場合は、SqlCommand や SqlDataAdapter クラスを使用して ADO.NET のプログラミングを行います。
● まとめ
今回はテーブルアダプターをパーシャルクラスを使用して拡張する方法について説明しました。次回はカスタムクラスを使用した ObjectDataSource の説明を ADO.NET の基礎を交えながら説明していきたいと思います。