階層の分離
しかし、Visual StudioにはRADの推進を阻害する要素が引き続き残されています。上記の機能を実現するには、データセットをユーザーインターフェイスと同じプロジェクトに配置する必要があるのです。しかし現実の世界では、ビジネス層をUIから分離するほうが得策です。そうすれば、Windowsの代わりにWebインターフェイスを実装することになった場合でも、アプリケーションの大部分を変更せずに済むからです。
この問題を解決するのはきわめて簡単です。ソリューション内にビジネスオブジェクト用の新しいクラスライブラリプロジェクトを作成すればよいのです。このプロジェクトを起点にして、UIプロジェクトの代わりにそこにオリジナルのデータセットを作成するのが最善の方法です。
ソリューションにNorthwindBizという名前の新しいクラスライブラリプロジェクトを作成し、データセットをそこに移動します。実際にはデータセットの新しいコピーが作成され、元のデータセットはそのまま残ります。データセットをコピーした後で、Windowsプロジェクトのデータセットを削除する必要があります。また、ハードコーディングされた名前空間の参照を検索して置換し、「NorthwindWin」を「NorthwindBiz」に変更する必要もあります。
データセットを作成した後、フォームに戻って[Data Sources]ウィンドウを開きます。今回は、新しいデータソースを追加するときに、Databaseツールを使う代わりにObjectツールを選択します。次の画面には、使用できる参照プロジェクトの一覧が表示されます。参照が表示されない場合は、[Add Reference]ボタンをクリックし、NorthwindBizプロジェクトを選択します。NorthwindBizプロジェクトを展開し、OrdersDataSetオブジェクトを選択します。[Next]をクリックして[Finish]をクリックすると、[Data Sources]ウィンドウにOrdersDataSetが表示されます。

Windowsプロジェクトを作成する前に実際にビジネスプロジェクトを作成すると、いくつかの違いに気付くでしょう。ウィザードはフォームロードイベントでテーブルアダプタのインスタンスを自動的に作成しません。Objectデータソースはデータセットでない可能性もあるため、VSはデータアクセスロジックの作成を開発者に任せます。コードは開発者自身が記述しなければなりませんが、プレゼンテーション層で記述するのではなく、ビジネス層で記述する必要があります。
ビジネスロジックのコード
アプリケーションにビジネスロジックを追加しやすくするために、VS 2005ではデータセットにパーシャルクラスが追加されます。OrdersDataSetを右クリックし、[View Code]を選択すると、データセットの下にPartial Public Classのコードスタブを含む別のファイルが作成されます。このファイルに追加するコードは、データセットを再ビルドしても上書きされません。パーシャルクラスは.NET 2.0の優れたツールであり、1つのクラスを複数の物理ファイルに分割することができます。プロジェクトをビルドすると、コードが結合されて一緒にコンパイルされます。これは、生成されたコードと開発者が記述するコードが同じクラス内にある場合に非常に役立ちます。
DataTable、DataRow、およびTableAdapterのパーシャルクラスは次のようにして追加できます。
Partial Public Class OrdersDataSet Partial Public Class OrdersDataTable End Class Partial Public Class OrdersRow End Class End Class Partial Public Class OrdersDataAdapter End Class
ビジネスロジックがテーブル全体に関連している場合は、コードをDataTableクラスに追加します。ロジックが行の検証に関連している場合は、コードをDataRowクラスに追加します。ロジックをアプリケーションのデータ層に追加する場合は、コードをData Adapterクラス内に追加します(コードがデータセットクラスの外側にあることに注意)。
Windowsプロジェクトのデータセットをビルドする場合は、データセットにデータを読み込み、データベースに書き戻すコードが自動的に追加されます。単独のビジネスプロジェクトのデータセットをビルドする場合は、ロジックが開発者によってビジネスオブジェクトに組み込まれるものと判断されます。データアクセスロジックをプレゼンテーション層から分離することが目的なので、これは賢明なやり方です。これらの機能を作成するには、次のようにデータセットのパーシャルクラスにいくつかの関数を追加します。
Imports ta = NorthwindDataSetTableAdapters Partial Public Class NorthwindDataSet Private taOrders As New ta.OrdersTableAdapter Private taOrderDetail As New ta.Order_DetailsTableAdapter Private taCustomer As New ta.CustomersTableAdapter Private taEmployee As New ta.EmployeesTableAdapter Private taProduct As New ta.ProductsTableAdapter Public Sub FillDataSetAll() Me.taOrders.Fill(Me.Orders) Me.taOrderDetail.Fill(Me.Order_Details) Me.taCustomer.Fill(Me.Customers) Me.taEmployee.Fill(Me.Employees) Me.taProduct.Fill(Me.Products) End Sub
最初に、各テーブルアダプタのオブジェクトのインスタンスを作成します。次に、各テーブルアダプタのFillメソッドを呼び出してデータセットにデータを読み込むメソッドを追加します。
さらに、テーブルを更新するためのメソッドも必要です。このデータセットで更新する必要があるのは「Orders」テーブルと「Order Details」テーブルのみで、それ以外のテーブルは参照専用です。
Public Sub UpdateOrders()
Me.taOrders.Update(Me.Orders)
End Sub
Public Sub UpdateOrderDetails()
Me.taOrderDetails.Update(Me.Order_Details)
End Sub
End Class
この数行のコードにより、ビジネスロジック層を通じてデータアクセス層にアクセスすることになり、プレゼンテーション層からの分離が実現します。
次にプレゼンテーション層に戻り、フォームの分離コード内で、ビジネスオブジェクトのこれらのメソッドを呼び出す必要があります。ロードイベントのコードスタブを作成するには、フォームのタイトルバーをダブルクリックし、アプリケーションのビジネス層で作成したメソッドを呼び出します。
Partial Public Class OrderForm Private Sub OrderForm_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.NorthwindDataSet1.FillDataSetAll() End Sub
さらに、更新をデータベースに書き戻すコードも必要です。ナビゲーションバーには、更新を書き戻すためのアイコンがあります。データセットがWindowsプロジェクトにある場合は、そのためのコードが自動的に作成されますが、Objectデータソースを使用している場合は、開発者がコードを記述する必要があります。必要に応じてボタンの使用可能プロパティを変更した後、ナビゲーションバーの[Save Item]ボタンをダブルクリックして、保存イベントのコードスタブを作成します。次のコードを追加する必要があります。フォームからデータセットを強制的に更新するには、Binding SourceのEndEditメソッドを呼び出す必要があることに注意してください。
Private Sub bindingNavigatorSaveItem_Click(ByVal sender _
As System.Object, ByVal e As System.EventArgs) Handles _
bindingNavigatorSaveItem.Click
Me.Validate()
Me.Order_DetailsBindingSource.EndEdit()
Me.OrdersBindingSource.EndEdit()
Me.NorthwindDataSet1.UpdateOrders()
Me.NorthwindDataSet1.UpdateOrderDetails()
End Sub
End Class
以前と同様、[F5]キーを押してアプリケーションを実行し、データが読み込まれることや、同じ機能がすべて存在することを確認してください。データに何か変更を加えた場合は、保存ボタンをクリックして、変更をデータベースに書き戻す必要があります。
