ObjectDataSource
開発環境: Visual Studio 2005
1.目次
2.目的 3.参考書
4.ObjectDataSource
4.1 全国または県別で選択的出力の例
ObjectDataSourceに関してのメモです。
-
@IT 第10章 3階層型自動データバインド
ウィザードベースで作れるASP.NET
アプリケーションの限界(2階層型自動データバインドの限界)については、参考書(1)がわかりやすい。これによると、次のような場合にウィザードベースだと対応できない。
- パラメータ化できない可変値を持つクエリ
- TOP句はパラメータ化できないため、このクエリはSqlDataSourceオブジェクト上に定義できない。
- 例:SELECT TOP @top * FROM authors
- 条件に応じて動的に変化するWHERE句を持つクエリ
- 指定された検索条件を基に、動的にWHERE句を組み立てるような業務
- 例:ドロップダウンで、全国または県別で選択的に出力
このような場合に効果を発揮するのが ObjectDataSourceで、3階層型自動データバインドを容易に実現するためのメカニズムを提供してくれる。
次のような州ごとのドロップダウン選択は、簡単にできる。
でも、ここでドロップダウンに”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
|