BOOK Preview

Microsoft Visual Studio 2005による
Webアプリケーション構築技法

7.6 データコンポーネント機能による
データアクセスコンポーネントの開発

マイクロソフトプレスの書籍紹介ページ
書籍情報のページ
2006/05/09

Page1 Page2 Page3 Page4

C. 型付きデータセット

 先の手順により作成された画面(図7-28)を見ると、このテーブルアダプタの上側に、"authors"と書かれた項目が存在する。これを「型付きデータセット」と呼ぶ※23。この型付きデータセットについて、以下に解説する。

※23 正確には、これは型付きデータセット内の型付きデータテーブルクラスである。

 先に解説したように、非接続型データアクセスでは、SqlDataAdapter(ポンプ)からDataSet(バケツ)にスナップショットデータを取り出す(水を汲み出す)。このDataSetに取り出したデータを読み書きするためには、リスト7-13に示すようなコードを書く必要がある。

C#の場合

int rows = ds.Tables["authors"].Rows.Count;
string au_id = (string)ds.Tables["authors"].Rows[4]["au_id"];
VBの場合

Dim rows As Integer = ds.Tables("authors").Rows.Count
Dim au_id As String = CType(ds.Tables("authors").Rows(4)("au_id"), String)
リスト7-13 DataSet内に格納されたデータを操作するためのコード例

 もちろんこのようなコードであっても動作上の問題が発生するわけではないが、実際の開発では以下のような問題がある。

  • テーブル名や列名を文字列によって指定しなければならないため、コンパイル時にはスペルミスに気付けない。実行すると例外が発生するが、このときになって初めてテーブル名や列名の記述ミスに気付くことができる。

  • DataSetは汎用的な入れ物であるため、データはすべてObject型として取り扱われる。このためデータ取り出し時には、適切なキャストによる型復元が必要になり、煩わしい。

 しかし改めて考え直してみると、実行するSQL文によってどのような構造のデータが取り出されるのかは、開発時点でも分かることである。そこでこのデータコンポーネント機能は、テーブルアダプタによって実行するSQL文が定義されると、そのSQL文によって取り出されるデータ構造に最適化したデータの入れ物を作成してくれる。これが型付きデータセットと呼ばれるものである。

 この型付きデータセットをテーブルアダプタと併用すると、データベースからデータのスナップショットコピーを取り出す作業と、取り出した後のデータ読み出し作業を、極めて簡単に記述できる。特に、型付きデータセット内のデータ操作ではIntelliSenseも利用できるため、開発効率が大幅に改善する(図7-29)。実装例をリスト7-14に示すので、実際にWebページ上にコードを記述し、動作を確認してみていただきたい※24

※24 なお、*.xsdファイルを編集した場合には、速やかにセーブを行うことを推奨する。セーブを行わなかった場合、背後で自動コード生成ツールが動作せず、その結果、リスト7-14のようなコードビハインド側の実装時にIntelliSenseが働かないことがある。一般に、IntelliSenseが表示されない理由としては以下のいずれかであることが多いので覚えておくとよい。(1)ファイルをセーブしていないため、各種の自動コード生成ツールが動作していない。(2)ソースコードに文法的なミスがあり、開発環境が正しくソースコードを解析できない。
 
図7-29 IntelliSenseによる型付きデータセット内のデータの操作
 
C#の場合

public partial class _Default : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    AuthorsDataSetTableAdapters.authorsTableAdapter ta = new
AuthorsDataSetTableAdapters.authorsTableAdapter();
    AuthorsDataSet ads = new AuthorsDataSet();

    // テーブルアダプタを利用して、
    // 型付きデータセットにデータ読み取る
    // (すでに実行するクエリが定義されているため、すぐに利用できる)
    ta.Fill(ads.authors);

    // テーブル名や列名をIntelliSenseにより指定しながら
    // 開発を進めることができる
    int rows = ads.authors.Count;
    string au_id = ads.authors[4].au_id;
    Label1.Text = rows.ToString();
    Label2.Text = au_id;
  }
}
VBの場合

Partial Class Default
  Inherits System.Web.UI.Page
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim ta As New AuthorsDataSetTableAdapters.authorsTableAdapter
    Dim ads As New AuthorsDataSet
    ' テーブルアダプタを利用して、型付きデータセットにデータ読み取る
    ' (すでに実行するクエリが定義されているため、すぐに利用できる)
    ta.Fill(ads.authors)

    ' テーブル名や列名をIntelliSenseにより指定しながら
    ' 開発を進めることができる
    Dim rows As Integer = ads.authors.Count
    Dim au_id As String = ads.authors(4).au_id

    Label1.Text = rows.ToString()
    Label2.Text = au_id
  End Sub
End Class
リスト7-14 テーブルアダプタと型付きデータセットを活用したデータベースアプリケーションの実装例

 なお、一般にDataSetや型付きDataSetのように、それ自身はデータベースとの通信機能を持たず、データの保有機能しか持たないオブジェクトのことを、ビジネスエンティティコンポーネント(BEC)と呼ぶ。WebアプリケーションやXML Webサービスアプリケーションにおいては、コンポーネント間、あるいはサーバー/クライアント間でのデータ一括受け渡しが必要になることが多い。このような場合にBECを利用すると、極めて簡単にデータの引渡しができる※25。アプリケーションの設計例を図7-30に示す。

※25 .NET Frameworkの優位性の1つに、このようなDACとBECの開発容易性が挙げられる。特にVisual WebDeveloperやVisual Studio 2005を利用すると、データコンポーネント機能(.xsdファイル)を利用してDACとBECをペアとして簡単に作成できるので、開発生産性が非常に高い。
 
図7-30 型付きデータセットをBECとして利用するアプリケーションの設計例

D. テーブルアダプタへのクエリ追加

 先に解説したように、このテーブルアダプタはデータアクセスコンポーネント(DAC)である。このため、先に設定したような単純なクエリだけでなく、パラメタライズドクエリや単一集計値クエリ、更新クエリなど様々なクエリを設定することができるようになっている。図7-31のように、ツールボックスからテーブルアダプタに対してQueryオブジェクトをドラッグ&ドロップで追加すると、このテーブルアダプタにさらに実行クエリを追加していくことができる。

図7-31 テーブルアダプタへの様々なクエリの追加

 実際に、この画面上に表7-6に示したようなSQL文を定義し、適当なメソッド名を付与してみていっていただきたい。極めて簡単にテーブルアダプタ上に各種のSQL文を定義していくことができる(図7-32)。また、作成したクエリは、リスト7-15のようなコードにより簡単に実行することができる。

クエリの種類 定義したSQL文 メソッド名 メソッド内部に自動生成されるデータアクセスコード
テーブル読み出しクエリ SELECT * FROM authors Fill( ) / GetData( ) 非接続型データアクセス
(SqlDataAdapter)を利用するコード
テーブル読み出しクエリ
(パラメタライズドクエリ)
SELECT * FROM authors WHERE state=@state FillByState( ) 非接続型データアクセス
(SqlDataAdapter)を利用するコード
集計値読み出しクエリ SELECT COUNT(*) FROM authors WHERE state=@state CountAuthorsByState( ) 接続型データアクセス
(SqlCommad.ExecuteScalar( ))を利用するコード
データ更新クエリ UPDATE authors SET
contract=?contract WHERE state=@state
ChangeContractByState( ) 接続型データアクセス
(SqlCommad.ExecuteNonQuery( ))を利用するコード
表7-6 テーブルアダプタ上に定義できる各種のクエリの例
 
図7-32 作成されたテーブルアダプタの例
 
C#の場合

AuthorsDataSetTableAdapters.authorsTableAdapter ta = new
AuthorsDataSetTableAdapters.authorsTableAdapter();

// (1) テーブルアダプタを利用したDataAdapter 同様のデータ取得
AuthorsDataSet ads1 = new AuthorsDataSet();
ta.Fill(ads1.authors);

// (2) 型付データテーブルを利用したコーディング(DataTable を単体で入手することができる)
AuthorsDataSet.authorsDataTable dt1 = ta.GetData();

// (3) パラメタ化クエリ経由でのデータ取得(パラメータ値は引数として簡単に指定できる)
AuthorsDataSet ads2 = new AuthorsDataSet();
ta.FillByState(ads2.authors, "CA");

// (4) UPDATEクエリによるデータの一括更新
int affectedRows2 = ta.ChangeContractByState("CA");

// (5) 集計データの取得
int rowsCount = (int)ta.CountAuthorsByState("CA");
VBの場合

Dim ta As New AuthorsDataSetTableAdapters.authorsTableAdapter()

' (1) テーブルアダプタを利用したDataAdapter 同様のデータ取得
Dim ads1 As AuthorsDataSet = New AuthorsDataSet()
ta.Fill(ads1.authors)

' (2) 型付データテーブルを利用したコーディング(DataTable を単体で入手することができる)
Dim dt1 As AuthorsDataSet.authorsDataTable = ta.GetData()

' (3) パラメタ化クエリ経由でのデータ取得(パラメータ値は引数として簡単に指定できる)

Dim ads2 As AuthorsDataSet = New AuthorsDataSet()
ta.FillByState(ads2.authors, "CA")

' (4) UPDATEクエリによるデータの一括更新
Dim affectedRows2 As Integer = ta.ChangeContractByState("CA")

' (5) 集計データの取得
Dim rowsCount As Integer = CType(ta.CountAuthorsByState("CA"), Integer)
リスト7-15 テーブルアダプタを利用したデータアクセス処理の実装例

 この例から分かるように、このデータコンポーネント機能によりテーブルアダプタを作成すると、極めて簡単に各種のSQL文をベストプラクティスに沿った方法で実行できるのである。

 以上を整理すると、次のことが言える。Visual Web Developer(Visual Studio 2005)に新しく搭載されたこのデータコンポーネント機能(.xsdファイル)とは、データアクセスコンポーネント(DAC)とビジネスエンティティコンポーネント(BEC)とをペアにして簡単に定義することが可能な機能である。このことを意識しておくと、アプリケーション設計を容易に進めていくことができるだろう※26(図7-33)。

※26 なお、本書ではこれ以上の深入りは避けるが、このデータコンポーネント機能は、アプリケーションアーキテクチャの観点からすると極めて重大な意味を持っている。一般に、論理3階層型でアプリケーションを設計する場合、DAC層はデータベーステーブルの構造に合わせて作成する方法と、BC層のコンポーネント側に合わせて作成する方法の2つの大きな選択肢がある(『.NETエンタープライズWebアプリケーション開発技術大全』Vol.4 p.342)。しかしこのデータコンポーネント機能には、以下のような特徴がある。(1)DACとBECの開発コストを大幅に低減できる。このため、DAC層を共有しても、従来ほどの開発コストメリットを得られなくなる。(2)テーブルアダプタを利用すると、アプリケーションコードはあたかも埋め込みSQLを記述しているような感覚で開発していくことができるようになる(後述の自動トランザクションの利用例も参照)。このため、データコンポーネントをBC層に紐付ける形で作成するようにデザインすると、「論理3階層(UI+BC+DAC)」というよりは「論理2階層(UI+BC)」に近い感覚でアプリケーションを開発できてしまう。むろん実際問題として、DAC層をテーブル構造に合わせて作るのか、BC層の構造に合わせて作るのかにはトレードオフがあり、どちらがよいと一概に言えるものではない。しかし、開発技術が進化して抽象度が上がり、記述すべきコードが減ってくると、論理階層数を減らしてしまうという選択肢も取れるようになってくる、という点は意識しておく必要がある。今後予定されている埋め込みクエリ技術であるLINQ(Language Integrated Query)についても、同様な観点から留意する必要がある。
 
図7-33 データコンポーネント機能(.xsdファイル)を用いたアプリケーションの開発
 

 INDEX
  Microsoft Visual Studio 2005によるWebアプリケーション構築技法
  7.6 データコンポーネント機能によるデータアクセスコンポーネントの開発
    1. 7.6.1 データコンポーネント機能の概要
    2. 7.6.2 データコンポーネント機能の利用手順(1)
  3. 7.6.2 データコンポーネント機能の利用手順(2)
    4. 7.6.3 データコンポーネントの拡張
 
インデックス・ページヘ  「BOOK Preview」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間