宇宙仮面の C# プログラミング
   

Top

C#

SQL Server

Virtual PC/Server

C# 研究室ブログ

C# ソフトウェア ダウンロード

宇宙仮面の C# プログラミングについて

.NET/C# eGroup JP

INETA Japan



Google
Web
uchukamen.com









ObjectDataSource

開発環境: Visual Studio 2005

1.目次

1.目次
2.目的
3.参考書
4.ObjectDataSource
4.1 全国または県別で選択的出力の例

2.目的

ObjectDataSourceに関してのメモです。

3.参考書

(1) @IT 第10章 3階層型自動データバインド

4.ObjectDataSource

ウィザードベースで作れるASP.NET アプリケーションの限界(2階層型自動データバインドの限界)については、参考書(1)がわかりやすい。これによると、次のような場合にウィザードベースだと対応できない。

  • パラメータ化できない可変値を持つクエリ 
    • TOP句はパラメータ化できないため、このクエリはSqlDataSourceオブジェクト上に定義できない。
    • 例:SELECT TOP @top * FROM authors
  • 条件に応じて動的に変化するWHERE句を持つクエリ
    • 指定された検索条件を基に、動的にWHERE句を組み立てるような業務
    • 例:ドロップダウンで、全国または県別で選択的に出力

このような場合に効果を発揮するのが ObjectDataSourceで、3階層型自動データバインドを容易に実現するためのメカニズムを提供してくれる。

4.1 全国または県別で選択的出力の例

次のような州ごとのドロップダウン選択は、簡単にできる。

でも、ここでドロップダウンに”ALL”を入れようと思うと、WHERE がいらない SELECT文になるので、条件判断がはいることになり、単純な2層ではうまくいかなくなる。

 

4.1 SELECT TOP Xの例

そこで、ObjectDataSource を使って、対応してみる。

Step1

SQLDataSource の場合は、データベースからデータ型を取得してきてくれるのでとても楽だが、ObjectDataSourceは XML データベーススキーマ(XML schema definition)ファイルを作成する必要がある。まずは、次のようにXML データベーススキーマ(XML schema definition)ファイルを作成する。ソリューション エクスプローラから[新しい項目の追加]→[データセット] を選択する。

ファイル名をわかりやすく変更して、追加ボタンを押す。ここでは、DataSetStates.xsdとした。

Step 2

次に、この DataSetStates.xsd をダブルクリックして、デザイナで開く。するとつぎのように TableAdapter 構成ウィザードが立ち上がり、ObjectDataSource 上にTableAdapterをつくようにガイドしてくれる。

接続文字列は、SQL Server 2005 のサンプルデータベースの AdventureWorks を使用する。次へ。

コマンドは、従業員を取得できるビューがあり、SQL文で一発でデータを取得できるので、一番上の SQL ステートメントを使用するを選択する。

すると、SQL ステートメントの入力ダイアログが立ち上がるので、

クエリビルダを起動して、ここではビューの vEmployee を追加する。

クエリの実行で、次のようにクエリが成功すればOK。

次に生成するメソッドの選択ダイアログが表示される。ここでは、デフォルトのままにして、Fill, GetData メソッドを生成するようにする。

これで、次のように DataSetSates.xsd として、テーブル部分とTableAdapter 部分の定義が出来上がる。この時点では、あくまで定義部分が出来上がったに過ぎない。

注意: この時点で、列はすべて文字列型で生成されてしまいます。この例では、EmployeeIDは整数型なので、プロパティを変更してあげる必要があります。

Step 3

次に、AllState.aspx という新しいファイルで、コントロールを次のように追加する。

GridViewのタスクから、データソースの構成選択して、

オブジェクトデータソースを選択する。次に、ビジネスオブジェクトの選択を聞いてくるので、先ほど作成したvEmployeeTableAdapter を選択する。

次に、データメソッドの定義を聞いている。ここでは、GetDataしか定義していないので、SELECTのメソッドしか表示されないが、完了ボタンを押して、終了する。

ここまでで、SQL データソースをベースに作ったものとほぼ同等の機能ができる。

ただし、ここでは SELECT にパラメータを渡していないので、ドロップダウンで別の州を選択しても何も起こらない。

実は、この裏側で、ツールによってかなりで大きなコードが自動生成されるコードがある。

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\websitetest1\???\???\Sources_App_Code

構造的に簡単にするため、関係の少ない部分をカットすると、次のようになる。


public partial class DataSetStates : System.Data.DataSet
   ...

namespace DataSetStatesTableAdapters
{
    public partial class vEmployeeTableAdapter : System.ComponentModel.Component
    {
        public virtual int Fill(DataSetStates.vEmployeeDataTable dataTable)
        {
            this.Adapter.SelectCommand = this.CommandCollection[0];
            if ((this.ClearBeforeFill == true))
            {
                dataTable.Clear();
            }
            int returnValue = this.Adapter.Fill(dataTable);
            return returnValue;
        }

        public virtual DataSetStates.vEmployeeDataTable GetData()
        {
            this.Adapter.SelectCommand = this.CommandCollection[0];
            DataSetStates.vEmployeeDataTable dataTable = new DataSetStates.vEmployeeDataTable();
            this.Adapter.Fill(dataTable);
            return dataTable;
        }
    }
}

ここで、vEmployeeTableAdapter は、DataSet から継承したパーシャルクラスで、Fill, GetData を実装しています。このvEmployeeTableAdapter クラスを、partial定義により機能拡張することができます。そこで、partial class vEmployeeTableAdapter で、 メソッドを追加して ALL が正しく扱われるように修正してみます。

Step 4

ソリューションエクスプローラで、StatesDataSet.cs を追加します。

partial class vEmployeeTableAdapter を実装します。(コードは、ほぼ参考文献1どおりなので、エラー、オブジェクト廃棄処理は適切に行ってください。)

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Data.SqlClient;

namespace DataSetStatesTableAdapters
{
    public partial class vEmployeeTableAdapter
    {
    [DataObjectMethod(DataObjectMethodType.Select)]
    public DataSetStates.vEmployeeDataTable Getdata(string state)
    {
    SqlDataAdapter sqlda;
    if (state == "ALL")
    {
        sqlda = new SqlDataAdapter("SELECT EmployeeID, FirstName, LastName,                     StateProvinceName, City FROM HumanResources.vEmployee", this.Connection);
    }
    else
    {
        if (state == null)
            return null;
        sqlda = new SqlDataAdapter("SELECT EmployeeID, FirstName, LastName, StateProvinceName, City FROM HumanResources.vEmployee WHERE StateProvinceName=@state", this.Connection);
        sqlda.SelectCommand.Parameters.AddWithValue("@state", state);
        }
        DataSetStates.vEmployeeDataTable table = new DataSetStates.vEmployeeDataTable();
        sqlda.Fill(table);
        return table;
        }
    }
}

すると、ObjectDataSource1 のメソッドの選択のところに、新たにメソッドが追加されます。

このときのパラメータは、次のように与えます。

これにより、ALL を選んだ場合でも正しく動作するようになります。

同様に TOP N についても、ObjectDataSource にパラメータを取るメソッドを追加してあげることにより対応が可能となる。

さいごに

partial class TableAdapter への機能拡張で、そのためには内部的に自動作成されているコード(C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\websitetest1\???\???\Sources_App_Code) の中身を一度見ておくと、どのように機能を追加すればよいのか、すっきりすると思います。

そうしないと、どのクラスにどのように機能拡張しなければいけないのが手さぐりになってしまい、試行錯誤してしまいます。このあたりの使い勝手は、もう少し改良してもらいたいですね。

それに、こんな程度のものを3層なんて呼んでいていいのかね・・・これってSQL DataSource に少し毛が生えた程度ジャン orz

このページを評価する

このページを評価する

悪い             良い
1 2 3 4 5
コメント(一言お願いします)