「iPhone4」と「Xperia X8」、買うならどっち?
|
Visual Studio .NETのウィザードを使ってN階層アプリケーションを作成する:パート2はじめにMicrosoftは、RAD(Rapid Application Development)ツールのための優れたツールを開発者に提供することで知られています。MS Access、Visual Studio 6、Visual Interdevなどには、コントロールやプロパティ、自動生成コードを視覚的に組み合わせてすばやく適用するための環境が用意されています。Visual Studio .NETはこれらのツールを統合し、数多くのプログラミング言語に対応している素晴らしい開発環境です。 Visual Studio .NET(以下、VS)には、アプリケーション開発に役立つウィザードが多数用意されています。しかし残念ながら、ウィザードでは効率的なプログラミング手法が使われない傾向にあります。具体的に言うと、コードが複数の層に分離されず、ビジネスロジックが分離されないのです。VSの既定のモデルでは、データオブジェクトをフォームにドラッグ&ドロップしながらフォームを作成します。コードは必要に応じて作成されますが、データアクセスコードとビジネスロジックコードが区別されず、ユーザーインターフェイスのフォームオブジェクト内に直接作成されます。このため、コードの再利用が難しく、同じテーブルデータを複数のフォームで使用する場面ではコードの重複が発生します。 今日のアーキテクチャでは、コードを複数の層に分離するN階層アプローチが推奨されています。N階層アプローチでは、少なくともデータアクセス層、ビジネスロジック層、プレゼンテーション層の3つが必要です。アプリケーションの各種パーツを複数のサーバー上に置く分散アプリケーションの場合は、より多くの層が必要になることもあります。 層を分離する主なメリットは2つあります。1つはコードの再利用が容易になることで、もう1つはコードとデータベースの結合を回避できることです。データアクセス層とビジネスロジック層を分離すると、データのアクセスと使用に必要なコードをあちこちに繰り返し記述しなくても、さまざまなフォームを使ってデータを収集および表示できます。コードとデータベースの結合を回避すると、データベースのスキーマを変更する際にコードを修復する量が少なくなり、データストレージプロバイダを変更するときでも、コードを大幅に変更せずに済みます。 Microsoft .NETは、開発者にOOP(オブジェクト指向プログラミング)の標準への移行を促し、支援するという点で大幅な進歩を遂げてきました。OOPは高度で深遠な話題なので、ここでは詳しく説明しませんが、1つだけ、データベースアプリケーションの開発者にとって興味深い「ビジネスオブジェクト」について簡単に触れておく ことにします。データベースのテーブルとフィールドがエンティティと属性の実装において重要な役割を果たすのに対し、ビジネスオブジェクトは特定のエンティティのプロパティと動作を併せて実装します。アプリケーションが各エンティティ(テーブル)を表すビジネスオブジェクトクラスのインスタンスを作成すると、そのプロパティを介して属性にアクセスし、メソッドを介してエンティティの動作を呼び出せるようになります。また、この手法を採用すると、エンティティに関するコードをすべて1つの場所にまとめておいて、アプリケーションのその他のパーツから簡単に参照することが可能です。さらに、ビジネスオブジェクトで継承やポリモーフィズムを利用すると、非常に柔軟で強力なプログラミングが可能になるため、わずかなコードで大量の処理を実行することができます。 パート2 - Visual Studio 2005の使用新しいバージョンの.NETとVisual Studioでは、データベース中心のアプリケーション開発方法に変化をもたらすさまざまな機能拡張が行われています。本稿では、特にデータソースとパーシャルクラスに注目します。 Binding Context Managerが拡張され、大幅に簡略化されてBinding Sourcesコンポーネントになっています。このコンポーネントを使うと、フォーム上でデータセット、Webサービス、およびビジネスオブジェクトへのデータバインドをより適切に行うことができます。 パーシャルクラスは、複数のファイルにまたがるクラスを作成するための手段です(コンパイル時にファイルが結合されます)。型指定されたデータセット( 準備作業VS2005を開いたら、[File]-[New Project]を選択して新しいプロジェクトを作成し、VB Windowsプロジェクトから作業を開始します。ウィンドウの下部にあるダイアログで、プロジェクトに「NorthwindWin」、ソリューションに「Northwind」という名前を付けます。 データオブジェクト データアプリケーションを作成するには、まず、データオブジェクトを定義するための型指定されたデータセットオブジェクトを作成します。プロジェクトに新しいデータセットオブジェクトを追加するには、ソリューションエクスプローラウィンドウでプロジェクトを右クリックし、[Add]-[New Item]の順に選択します。データセットのデザインサーフェイスの機能が強化されており、複数のテーブルをサーバーエクスプローラ(Expressバージョンの場合はデータベースエクスプローラ)のウィンドウからドラッグしてデータセットに追加すると、リレーションシップがデータベースから自動的に挿入されるようになっています。データセットは、 より望ましい方法でデータセットを作成するには、データソースウィザードを使います。適切なプロジェクトを選択した後、最上部の[Data]メニューをクリックし、[Add New Data Source]を選択します。データソース構成ウィザードが起動したら、画面に表示される指示に従って操作を行うと、適切な接続を使用するデータセットが作成されます。最初の画面では、そのまま[Next]をクリックします。次の画面では、データソースのタイプを選択できます。 ここではDatabaseタイプを選択しますが、Webサービスや既存のビジネスオブジェクトを使うオプションがあることも覚えておいてください。後でこれらのタイプを使用します。 次の画面では、既存の接続を選択することも、新しい接続を作成することもできます。 Northwindデータベースへの接続がない場合は、[New Connection]ボタンを使って接続を作成してください。この接続のプロジェクト設定をまだセットアップしていない場合は、ウィザードによってセットアップされます。 次の画面には、データベース内のすべてのメタデータのツリーリストが表示されます。[Tables]ノードを展開し、このデータセットで必要なテーブル(「Orders」、「Order Detail」、および「Products」)を選択します。 この画面を終了する前に、データセットに適切な名前を割り当てます(初期のベータ版の中には、データセットの名前を正しく変更できないものがありました)。この例では、データセットの名前を「NorthwindDataSet」から「OrdersDataSet」に変更する必要があります。 ウィザードを終了すると、3つのテーブルが含まれるデータセットがプロジェクトに追加されます。 このデザインサーフェイスでは、サーバーエクスプローラ(Standardバージョンではデータベースエクスプローラ)からさらに別のテーブルをドラッグし、データセットに追加することができます。この後の手順で、コンボボックスの参照のために「Customers」テーブルと「Employees」テーブルを追加する必要があります。 テーブルを編集するには、見出しを右クリックし、ドロップダウンメニューから[Configure]を選択します(または、最上部の[Data]メニューをクリックし、[Configure]を選択します)。 テーブルアダプタのSQLを視覚的に編集するには、[Query Builder]ボタンをクリックします。この例では、姓と名を組み合わせた [Advanced Options]ボタンをクリックし、 プレゼンテーション層データソースRADツールデータセットを作成したら、最上部の[Data]メニューから[Data Sources]ウィンドウを開きます。このウィンドウには作成したデータセットが表示されますが、データベースサーバー、ローカルデータベースファイル(AccessやFoxProなど)、Webサービス、または定義済みのビジネスオブジェクトクラスから他のデータソースを追加することもできます。ウィザードを使用すると、画面に表示される指示に従ってデータソースを追加できます。また、テーブルノードを展開し、データテーブルで利用可能なすべてのフィールドを参照することもできます。 フォームをIDEで開いているときは、[Data Sources]ウィンドウにいくつかの追加の機能が現れます。各ノードを選択すると、ドロップダウン(コンボ)ボックスが表示され、フォームにドラッグしたオブジェクトをどのように表示するかを選択することができます。テーブルの場合は、グリッドビュー(DataGridView)と詳細ビューの2つの選択肢があります。グリッドビューでは、各フィールドを既定の形式で実装するDataGridViewコントロールが作成されます(別の埋め込みコントロールを表示するように編集することもできます)。詳細ビューでは、レコードを1件ずつ表示できるように、個々のフィールドに関するラベルとテキストボックス(または他のコンポーネント)が作成されます。 使用可能なフィールドコントロールはTextbox、NumericUpDown、Combobox、Label、Linked Label、およびListboxです。独自のユーザーコントロールを作成してリストに追加することもできます。 Data Sourcesツールは、開発者がデータベーススキーマに基づいてユーザーインターフェイス(UI)を短期間で作成できるRAD(Rapid Application Development)環境を実現します。VS2005では、コントロールをデータセットのフィールドに直接バインドする代わりに、データセット内のデータオブジェクトと相互に連携するBinding Sourceという新しい層が追加されています。UI上のコントロールは、Binding Sourceのフィールドにバインドされます。これはBinding ContextオブジェクトとDataViewオブジェクトが組み合わさった新しいコンポーネントです。 各コントロールでは、バインド可能なプロパティの数を減らすことで、バインドを簡略化しています。バインド可能なプロパティは、タグ、テキスト、選択値など、一般的なものだけに制限されています。詳細設定を使用すれば他の数多くのプロパティにバインドすることも可能ですが、通常は一般的なバインドが主に使用され、データソースウィザードの既定値になっています。 Orders表示/編集画面の作成それではOrdersデータを編集するためのフォームを作成しましょう。ソリューションエクスプローラでプロジェクトを右クリックし、[Add]-[New Item]の順に選択します。次にWindowsフォームアイコンを選択し、「OrdersForm.vb」という名前を付けます。作業用の空白フォームが表示されます。 [Data Sources]ウィンドウが開いていない場合は、最上部の[Data]メニューをクリックし、[Show Data Sources]を選択します。ツリーには、データセットとデータテーブルが表示されるはずです。各テーブルの右側にあるドロップダウンリストで、テーブルをグリッドビューとして実装するか、フリーフォームの詳細ビューとして実装するかを選択できます。さらに、テーブルを展開するとデータフィールドが表示され、同様にどのコントロールを使ってフリーフォームのコントロール内のフィールドを実装するかを選択できます(注意:ベータ版では、グリッドビュー内でのフィールドの表示方法も設定できましたが、最終版ではこれが削除されており、テキストボックスのみが表示されます。ただし、後から列を編集して変更することはできます)。[Tools]-[Options]-[Windows Forms Designer]-[Data UI Customization]の順に選択してこのウィザードを変更し、カスタムコントロールも表示することができます。 通常、多くのプレゼンテーションでは親画面を詳細形式で表示することが望ましいので、[Data Sources]ウィンドウで「Orders」テーブルの形式を[Details]に変更します。次に、[Data Sources]ウィンドウから「Orders」テーブルをドラッグし、Visual Studioのデザインサーフェイスにある空白フォームの左上隅にドロップします。指定した既定値に従って、データソースウィザードがテーブル内の各コントロールを作成します。[Data Sources]ウィンドウからフィールドを1つずつドラッグすることもできますが、一度にすべて作成した方がはるかに短時間で済みます。各コントロールに正しく名前が付けられ、テーブル内の適切なフィールドにバインドされることが分かります。さらに、各コントロールのラベルも作成されます(説明プロパティが設定されている場合はその値、設定されていない場合はフィールドの名前が使われ、必要に応じてスペースが挿入されます)。 追加されるのはコントロールだけではありません。レコード間を移動するための、ビデオデッキのボタンに似たデータナビゲーションストリップも追加されます。また、データセットおよびデータベースとの接続/バインドを実現するために必要なコンポーネントも追加されます。コードウィンドウを開くと、Table Adapterコンポーネントを呼び出してデータセットコンポーネントにデータを読み込むためのコード行も追加されていることが分かります。プロジェクトをスタートアッププロジェクトに設定し、プロジェクトのプロパティでこのフォームを起動時に表示するように設定すると、ソリューションを今すぐビルドして実行し、すべての機能を備えたフォームを表示して、「Orders」テーブルのすべてのレコードを参照することができます。コンボボックスコントロールを正しく機能させるために多少の作業が必要ですが、フォームは基本的に動作可能な状態になります。 コンボボックスを機能させるには、データセットを開いて「Customer」テーブルと「Employee」テーブルを追加します(またはこれらのテーブル用に単独のデータセットを作成します)。プロジェクトをビルドした後、[Data Sources]ウィンドウをリフレッシュして新しいテーブルを確認するか、新しいデータソースを追加します(テーブルを別のデータセットに入れる場合)。 フォームに戻り、[Data Sources]ウィンドウから「Employee」テーブルをドラッグして、コンボボックスにドロップします。最初に気付くのは、「Employee」テーブル用に別のBinding Sourceコンポーネントが追加されていることです。Employeeコンボボックスコントロールを選択すると、Data Source、Display Member、およびValue Memberの適切な設定が行われていることと、バインドがTextからSelected Valueに変更されていることが分かります。これはMicrosoftが「Connect the dots」と呼ぶもので、テーブルを任意のリスト方式のコントロールにドラッグ&ドロップできる機能です。ウィザードはValue Memberの主キーとDisplay Memberプロパティの最初の文字フィールドを使用します。 同じ方法で「Customer」テーブルをCustomerコンボボックスにドラッグすると、やはりテーブル用にBinding Sourceコンポーネントが追加されます。また、フォームの分離コードを開き、 コントロールを少し並べ替えた後のフォームは、次のような外観になります。 マスタ/詳細プレゼンテーションリレーショナルアプリケーションで重要なのは、親子のリレーションシップを表示する機能です。Visual Studio 2005には、この機能を短期間で開発するためのかなり柔軟性の高いツールが用意されています。[Data Sources]ウィンドウでテーブルを展開すると、フィールドの下に、テーブルの各子リレーションシップのエントリが表示されます。本稿の例では、[Orders]テーブルノードを展開すると、「Order Details」テーブルに対するリレーションシップのエントリが表示されます。グリッドビュー表示を選択し、リレーションノードをフォームにドラッグすると、マスタ/詳細配置を指定しているものと判断され、必要なリンクが自動的に作成されます。 テーブルのフォームには、新しいBindingSourceコンポーネントが追加されます。さらに、フォームのロード時にテーブルへのデータ読み込みを行うテーブルアダプタが追加されます。スマートタグ(グリッドコントロールの右上にある矢印)をクリックすると、コントロールのいくつかのプロパティとアクションが表示されます。[Choose Data Source]を選び、テーブル間のリレーションシップに基づく新しいBinding Sourceを指定する必要があります。マスタレコードにリンクする詳細グリッドを設定するために必要な操作はこれだけです。プロパティを見ると、新たに追加されたBinding SourceのData SourceがOrdersBindingSourceになり、Data Memberがリレーションシップになっていることが分かります。 ここでプロジェクトをコンパイルして実行すると、マスタ部分と詳細部分とのリンクを確認できます。しかし、グリッドに有用なデータを表示するには、多少の編集が必要です。 ProductIDをコンボボックスに置き換えて、製品の名前を表示する必要があります。それには、フォームに別のBinding Sourceを追加します。ツールボックスの[Data]セクションからBinding Sourceコンポーネントをドラッグし、「ProductsBindingSource」という名前を付け、 次に、DataGridViewコントロールのスマートタグを再び展開し(または[Properties]ウィンドウを参照し)、[Edit Columns]アクションをクリックします。これにより、列の幅とスタイルを編集し、列の順序を変更し、列を追加または削除できるようになります。不要な列を削除し、主キーフィールドと外部キーフィールドを非表示にします( Order Detail Binding Sourceが追加されるときに、「Order Detail」テーブルにデータを読み込むためのコード行も追加されます。これは Dim OrdersDetailTableAdapter As New Order_DetailsTableAdapter OrdersDetailTableAdapter.Fill(Me.OrdersDataSet.Order_Details) 必要な作業は以上です。[F5]キーを押して(または[Debug]メニューの[Start Debugging]を選択して)アプリケーションをビルドし、実行することができます。完成したフォームの実行例を次に示します。ナビゲーションバーを使ってレコード間を移動できることや、選択中のOrdersレコードとOrder Detail情報がリンクしていることが分かります。ナビゲーションバーには、新しいレコードを作成するボタン(黄色い十字型)、現在のレコードを削除するボタン(赤いX印)、および変更を保存するボタン(フロッピーディスクのアイコン)も表示されます。 マスタ/詳細フォームのRAD構築ウィザードはVS2003にも用意されていましたが、VS2003のウィザードは柔軟性に欠けていました。VS2005のインフラストラクチャでは、多種多様なフォームスタイルのRAD構築を行うことができます。Data Sourcesツールは、Visual Studioの歓迎すべき改良点です。 階層の分離しかし、Visual StudioにはRADの推進を阻害する要素が引き続き残されています。上記の機能を実現するには、データセットをユーザーインターフェイスと同じプロジェクトに配置する必要があるのです。しかし現実の世界では、ビジネス層をUIから分離するほうが得策です。そうすれば、Windowsの代わりにWebインターフェイスを実装することになった場合でも、アプリケーションの大部分を変更せずに済むからです。 この問題を解決するのはきわめて簡単です。ソリューション内にビジネスオブジェクト用の新しいクラスライブラリプロジェクトを作成すればよいのです。このプロジェクトを起点にして、UIプロジェクトの代わりにそこにオリジナルのデータセットを作成するのが最善の方法です。 注意
上記の手順に従って既にアプリケーションを作成している場合は、作成したデータセットを新しいプロジェクトに移動できます。ただし、接続文字列を維持するために「app.config」ファイルも移動する必要があります。
ソリューションに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 OrdersDataSet Partial Public Class OrdersDataTable End Class Partial Public Class OrdersRow End Class End Class Partial Public Class OrdersDataAdapter End Class ビジネスロジックがテーブル全体に関連している場合は、コードを 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 最初に、各テーブルアダプタのオブジェクトのインスタンスを作成します。次に、各テーブルアダプタの さらに、テーブルを更新するためのメソッドも必要です。このデータセットで更新する必要があるのは「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の 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]キーを押してアプリケーションを実行し、データが読み込まれることや、同じ機能がすべて存在することを確認してください。データに何か変更を加えた場合は、保存ボタンをクリックして、変更をデータベースに書き戻す必要があります。 まとめ新しいバージョンのVisual Studio 2005では、RADツールを使って多層アプリケーションを作成する際の柔軟性が大幅に向上しています。型指定されたデータセット生成ツールを使用すると、データベースとUI/ビジネスロジックの間でデータが抽象化され、データベースのエンティティと属性に対するオブジェクト指向アクセスが可能になります。また、データセット生成ツールは、実質的に別の層に分離されたデータアクセスコードも提供します。パーシャルクラス機能を使うと、データセットコンポーネントに完全にアクセスできるビジネスロジック層を効果的に実装することができます。 Binding Sourcesコンポーネントは、UIをビジネスロジック層から切り離し、円滑なデータバインディングツールを提供することにより、アプリケーションを4階層アプリケーションに近い形に変化させます。また、[Data Sources]ウィンドウはプレゼンテーション層の短期生成を可能にし、N階層の環境を維持します。 データセットにデータを読み込む数行のコードを記述する必要があるとはいえ、わずか数分間で立派な多層アプリケーションを作成することができました。しかも、記述する必要があるのは独自のビジネスロジックを実装するためのコードだけです。 予告本シリーズのパート3では、アプリケーションの機能を強化するためにビジネスロジック層でどのようなことができるかをより詳しく見ていきます。また、データアクセスコードの作成に役立つコード生成ツールもいくつか紹介します。さらに、データアクセスコードプロバイダを独立させて、同じアプリケーションから別々のデータベースサーバーを利用できるようにする方法も説明します。 関連情報
著者紹介David Catherman(David Catherman)
データベースアプリケーションのデザイン/開発に20年以上の経験を持ち、ここ4、5年は特にMicrosoft .NETとSQL Serverに仕事が集中している。現在はCMI Solutionsのアプリケーション設計者および上級開発者であり、Visual StudioとSQL Server 2005を使用している。.NETのMCPを取得し、現在MCSDを取得中。
メールの宛先はDCatherman@CMiSolutions.com。
|
Twitter ユーザーの3人に1人が「毎日ツイート」(6月23日)
「携帯電話事業者各社の設備投資動向と今後の展望2」(5月21日)
過去のセミナー一覧はこちら
|