ヒント6:Generics名前空間のその他のクラス
ここまでは、Visual Studio 2005の新しいListクラスについて説明してきました。ここでは、System.Collections.Generics名前空間で目を引くその他の3つのクラス、Dictionary、SortedDictionary、Collectionについて説明します。
Visual Studio 2005には、Dictionaryという新しいクラスが追加されています。この抽象クラスを使うと、コレクションのキーと要素を対応付けることができます。.NET Framework 2.0の関数の中には、Dictioanryクラスを使用しているものもあります。その一例が、TCPチャネルを新規作成するための新しいオーバーロードです。次の例では、新しいDictionaryオブジェクトを作成する際に、キーと値の両方が文字列であることを指定しています。
// Create a new dictionary object with two strings Dictionary<string, string> oDict = new Dictionary<string, string>(); oDict.Add("secure", "true"); oDict.Add("password", "kevin"); TcpChannel oChannel = new TcpChannel(oDict, null, null);
ディクショナリのエントリをキーによって並べ替える必要がある場合は、キーによる並べ替え順序が維持される、新しいSortedDictionaryクラスを使用するのがよいでしょう。
また、ここまでは、新しいListクラスを使用してきましたが、Visual Studio 2005には、軽量なCollectionクラスもあり、並べ替え機能やフィルタ機能が必要ない単純なリストの場合にはそちらを使用できます。
Collection<int> oCol = new Collection<int>(); oCol.Add(2); oCol.Add(3); oCol.Insert(0,1);
Collectionオブジェクトにはカスタムクラスも格納できます。
Collection<BaseballClass> oBaseballCollection =
new Collection<BaseballClass>();
oBaseballCollection.Add(new BaseballClass("Tom Glavine",
"Mets"));
oBaseballCollection.Add(new BaseballClass("Derek Jeter",
"Yankees"));
foreach (BaseballClass oBaseball in
oBaseballCollection)
MessageBox.Show(oBaseball.ToString());
また、.NETのジェネリックには、リンクリストデータを扱うためのLinkedListクラスやLinkedListNoteクラスなどのほか、Queueクラス、Stackクラスもあります。
ヒント7:.NETのジェネリックを使用して型指定されたデータセットにレコードを読み込むデータアクセスクラスの作成
私はストアドプロシージャと型指定されたデータセットを多用します。私にとって、大いなる目標の1つだったのが、型指定されたデータセットに対して、ストアドプロシージャから直接レコードを読み込むということでした。
長いこと私が用いてきたのは、データアクセスクラスのベースメソッドを使用して、パラメータを持つストアドプロシージャから普通のデータセットにレコードを読み込むという方法でした。そのデータセットを、型指定されたデータセットに後でマージします。その方法でも確かに動作しますが、余分なコードと余分な処理が必要です。私がしたかったのは、型指定されたデータセットのインスタンスをベースメソッドに渡すと、そのベースメソッドがファクトリの役割を果たし、中身がセットされたデータセットが返ってくる、という方法でした。
.NETのジェネリックを利用すると、そのようなクラスを作成し、使用することができます(リスト4とリスト5を参照)。そのようなクラスを作成するには、次の手順に従います。
- 型指定されたデータセットのインスタンスと、データアクセスクラスのインスタンスを作成します(リスト5を参照)。
- 型指定された
Listを作成し、ストアドプロシージャで使用するSQLパラメータを格納します(ArrayListは使用しません)。 - データアクセスクラスのメソッド(
ReadIntoDs)を呼び出し、型指定されたデータセットのインスタンス、ストアドプロシージャの名前、ストアドプロシージャのパラメータが格納された型指定Listを渡します。 - データアクセスメソッド
ReadIntoDsの本体を作成します(リスト5を参照)。第1パラメータと戻り値には、型指定されたプレースホルダを指定します。このパラメータにはデータセットのみを使用できるように指定しています。メソッド内のコードでデータセット固有のプロパティやメソッドを使用するからです。 - 標準の
SqlConnectionオブジェクトやSqlDataAdapterなどを定義します。 - この部分は力技です。SQL Serverから返るストアドプロシージャの結果セットでは、Table1、Table2、といった名前が使われています。一方、型指定されたデータセットを自分でデザインするときには、もっとわかりやすい名前(
dtClientやdtDetailsなど)を使用する可能性があります。したがって、Table、Table1といった名前を、型指定されたデータセットの名前に対応付ける必要があります。それには、DataAdapterのTableMappingsを使用します。 DataAdapterからデータセットにレコードを読み込み、返します。
public T ReadIntoDS<T> (T dsTypedDs, string cStoredProc, List<SqlParameter> oParmList) where T : DataSet
public class SimpleDataAccess { // Pass the following: // 1) An instance of a typed dataset you wish to fill // 2) The name of the stored procedure // 3) A List of SqlParameters // Function will execute the stored procedure, // fill the typed dataset with the results, and then return it public T ReadIntoDs<T> (T oTypedDs, string cSP, List<SqlParameter> oParms) where T:DataSet { SqlConnection oSqlConn = this.GetConnection(); SqlDataAdapter oSqlAdapt = new SqlDataAdapter(cSP, oSqlConn); oSqlAdapt.SelectCommand.CommandType = CommandType.StoredProcedure; foreach (SqlParameter oParm in oParmList) oSqlAdapter.SelectCommand.Parameters.Add(oParm); // A little bit of "elbow grease… // SQL Server returns tablenames as "Table", "Table1", etc // We need to map in the tablenames from the typed DS // So loop through the tables in the Typed DS, get the name, // and map it to the corresponding table that SQL will // use as the default name int nTableCtr = 0; foreach (DataTable Dt in dsTypedDs.Tables) { string cSource = ""; if (nTableCtr == 0) cSource = "Table"; else cSource = "Table" + nTableCtr.ToString().Trim(); oSqlAdapter.TableMappings.Add( cSource, Dt.TableName.ToString()); nTableCtr++; } // End of "elbow grease" - we can fill the dataset // from the adapter, now that we've mapped our tablenames oSqlAdapter.Fill(dsTypedDs); return dsTypedDs; } public SqlConnection GetConnection() { // New SqlConnection StringBuilder class SqlConnectionStringBuilder oStringBuilder = new SqlConnectionStringBuilder(); oStringBuilder.UserID = "UserID"; oStringBuilder.Password = "PassWord"; oStringBuilder.InitialCatalog = "InitialCatalog"; oStringBuilder.DataSource = "DataSource"; return new SqlConnection(oStringBuilder.ConnectionString); } }
// Create an instance of a typed DataSet dsAgingReport odsAgingReport = new dsAgingReport(); // Create an instance of our Data Access Method SimpleDataAccess oDataAccess = new SimpleDataAccess(); // Use the list class to create a collection of sql parameters List<SqlParameter> oParms = new List<SqlParameter>(); oParms.Add(new SqlParameter("@dAgingDate", DateTime.Today)); oParms.Add(new SqlParameter("@lShowDetails", true)); // Call ReadIntoDs, passing the typed DS, name of the stored proc // and the list of parameters odsAgingReport = oDataAccess.ReadIntoDs(odsAgingReport, "[dbo].[GetAgingReceivables]",oParms);
ヒント8:ASP.NET 2.0のObjectDataSourceの概要
本記事の前編で、ASP.NET 2.0のGridViewについて取り上げ、データセットにバインドする方法や、並べ替えとページングの処理方法について解説しました。もう1つ使用できるのが、ASP.NET 2.0のObjectDataSourceです。データを処理するビジネスオブジェクト/クラスを、GridViewなどのデータバインドコントロールに対して公開できます。
ここでは、ObjectDataSourceの使用方法について、ステップバイステップ方式で解説します。最初の例では、「保留」になっている注文が格納された、型指定されたデータセットを返すビジネスオブジェクトを作成します。その後で、GridViewを配置したWebページを作成し、そのGridViewの直接のDataSourceとして、前述のビジネスオブジェクトを指定します。
- 「bzOrders」という別個のプロジェクトを作成します。型指定された単純なデータセット
dsOrdersと、レコードが読み込まれたdsOrdersのインスタンスを返すメソッドGetOrdersOnHoldを作成します。 - 新しいWebページプロジェクトを作成し、「bzOrders.dll」を参照として追加します(図1を参照)。
- 新しいWebページで、ツールボックスからObjectDataSourceのインスタンスを作成します(図2を参照)。
- 新しいObjectDataSourceを右クリックし、データソースを設定するオプションを選択します。[Configure Data Source]ダイアログボックスが表示されます(図3を参照)。データを提供するクラスとして
bzObjectsを選択します。 - 次に、標準の
Select、Insert、Update、Deleteの各操作に使用するメソッドをObjectDataSourceに対して指定します。この例では、Selectコマンドのみを指定し、GetOrdersOnHoldメソッドとします(図4を参照)。 - Webページ上にGridViewを作成し、
DataSourceIDプロパティをObjectDataSourceに設定します(図5を参照)。また、GridViewのその他のプロパティを図5のように設定します。並べ替えとページングを有効にするオプションも設定します。 - この時点で、Webページは実際に動作します。しかし列のサイズや配置の設定、見出しのカスタマイズなどを行っておく方がよいかもしれません。GridViewのプロパティシートを表示し、Columnsコレクションを選択します。列/フィールドのデザイナが表示され(図6を参照)、GridViewをカスタマイズできます。
- これで完成です。Webページを実行すると、図7のような結果になります。

このヒントで紹介したのは、ObjectDataSourceクラスの機能のほんの一部です。ObjectDataSourceでは、次のような処理も実現できます。
- パラメータを使用して単一の注文を取得する
retrieveメソッドをビジネスオブジェクトに定義できます。そして、ObjectDataSourceのデザイナで、そのメソッドをretrieveメソッドとして指定し、ページコントロールの値、FormFieldの値、QueryString、またはSession変数をパラメータに指定できます。 - 標準的な
Insert、Update、Deleteの各機能を実行するメソッドをビジネスオブジェクトに定義できます。こちらも、ObjectDataSourceのデザイナで、メソッドの対応付けとパラメータを指定できます。
それからもう1つ、ObjectDataSourceが返したデータを「捕捉」するにはどうすればいいのか、疑問に思う人もいるかもしれません。たとえば、グリッドのキャプションに行数を表示したい場合などです。そのときは、ObjectDataSourceのSelectedイベントを使用します。
protected void ObjectDataSource1_Selected( object sender, ObjectDataSourceStatusEventArgs e) { bzOrders.dsOrders odsOrders = (dsOrders)e.ReturnValue; int nRows = odsOrders.dtOrders.Rows.Count; this.grdOrdersOnHold.Caption = "Number of rows: " + nRows.ToString(); }






