今回から、数回に分けてSystem.Data.DataTableクラスについて
記述していきます。
既にずっと前から、暗黙的に使用されてきているクラスですが、やはりADO.NETを勉強する上で
かかせないクラスとなりますので、一つ一つメソッドを使用してみようと思います。
ADO.NETを使用する上で、最も重要だと思うクラスは以下の通りです。
System.Data.DataSet System.Data.DataTable System.Data.DataRow System.Data.DataRowState System.Data.DataColumn System.Data.Common.DbConnection System.Data.Common.DbCommand System.Data.Common.DbDataAdapter System.Transactions.TransactionScope
データセットデザイナなどを利用して、データセットを自動生成しても
実際に使用する際には、上記のクラスに対しての基礎知識が必要となります。
今回は、データテーブルを手動で構築してみます。
VisualStudioにて、型付けのデータテーブルが自動生成されますが実際には
XSDファイルに定義されたカラム名のプロパティが定義され、内部では今回の
ようにデータテーブルに対してカラム定義がされているだけです。基本は同じです。
以下、サンプルです。
using System; using System.Data; using System.Data.Common; using System.Collections.Generic; using NUnit.Framework; namespace Gsf.Samples.AdoNet { [TestFixture] public class AdoNetSample015 { ////// DataTableオブジェクトの機能を確認するためのテストメソッドです。 /// ////// 今回は、DataTableオブジェクトを手動で構築する部分について、テストしてみます。 [Test] public void DataTableオブジェクトの機能確認(){ // // DataTableオブジェクトを構築. // // コンストラクタの引数には、何も無しか、文字列でテーブル名を指定します。 // DataTable table = new DataTable("TestTable"); PrintTableInformation(table); // // 生成したデータテーブルに、カラム定義を行なう. // // カラム定義を行なうには、System.Data.DataColumnクラスのインスタンスを作成する。 // // 通常良く使用されるのは、コンストラクタにカラム名とそのカラムのデータ型を // 指定するタイプのもの。 // DataColumn idColumn = new DataColumn("Id", typeof(int)); DataColumn nameColumn = new DataColumn("Name", typeof(string)); DataColumn ageColumn = new DataColumn("Age", typeof(int)); // データテーブルにカラムオブジェクトを追加する事により、カラム定義が行なわれる。 table.Columns.AddRange(new DataColumn{ idColumn, nameColumn, ageColumn }); // // 定義したカラムに制約を追加する。 // // 以下の制約を追加する。 // ・Idカラムは、主キーとする。 // ・Nameカラムは、Not Nullとする。 // ・NameカラムとAgeカラムの値で、ユニークとする。 // // IdカラムをPrimary Keyに指定. table.PrimaryKey = new DataColumn{idColumn}; // NameプロパティにNot Nullを指定. nameColumn.AllowDBNull = false; // Unique制約を生成し、追加. table.Constraints.Add( new UniqueConstraint(new DataColumn[]{nameColumn, ageColumn}) ); // // 行データを追加する。 // // 行データの追加は、いくつかの方法があるが今回は一番ベーシックなものを // 行なう。以下の手順となる。 // // 1.NewRowメソッドを利用して、新規行をデータテーブルオブジェクトに生成してもらう。 // 2.生成された行データに対して、各データを設定. // 3.データテーブルのAddRowメソッドを使用して、データテーブルに追加する。 // for(int i = 0; i < 5; i++){ DataRow newRow = table.NewRow(); newRow[idColumn] = (i + 1); newRow[nameColumn] = string.Format("gsf_zero{0}", (i + 1)); newRow[ageColumn] = (28 + i); table.Rows.Add(newRow); } PrintTableInformation(table); // // データテーブル内の変更を確定. // table.AcceptChanges(); PrintTableInformation(table); } private void PrintTableInformation(DataTable targetTable){ Console.WriteLine("================================================================"); Console.WriteLine(string.Format("テーブル名:{0}", targetTable.TableName)); if(targetTable.Rows.Count != 0) { for(int i = 0; i < targetTable.Rows.Count; i++){ Console.WriteLine("\t行-{0}, 行状態(RowState) = {1}", (i + 1), targetTable.Rows[i].RowState); foreach(DataColumn col in targetTable.Columns){ Console.WriteLine("\t\t{0} = {1}", col.ColumnName, targetTable.Rows[i][col]); } } } Console.WriteLine("================================================================"); } } }
///
上記を実行すると、以下のように表示されます。
================================================================ テーブル名:TestTable ================================================================ ================================================================ テーブル名:TestTable 行-1, 行状態(RowState) = Added Id = 1 Name = gsf_zero1 Age = 28 行-2, 行状態(RowState) = Added Id = 2 Name = gsf_zero2 Age = 29 行-3, 行状態(RowState) = Added Id = 3 Name = gsf_zero3 Age = 30 行-4, 行状態(RowState) = Added Id = 4 Name = gsf_zero4 Age = 31 行-5, 行状態(RowState) = Added Id = 5 Name = gsf_zero5 Age = 32 ================================================================ ================================================================ テーブル名:TestTable 行-1, 行状態(RowState) = Unchanged Id = 1 Name = gsf_zero1 Age = 28 行-2, 行状態(RowState) = Unchanged Id = 2 Name = gsf_zero2 Age = 29 行-3, 行状態(RowState) = Unchanged Id = 3 Name = gsf_zero3 Age = 30 行-4, 行状態(RowState) = Unchanged Id = 4 Name = gsf_zero4 Age = 31 行-5, 行状態(RowState) = Unchanged Id = 5 Name = gsf_zero5 Age = 32 ================================================================ 1 passed, 0 failed, 0 skipped, took 1.05 seconds.
また、上記のサンプルでは制約を定義しているので、例えば以下のような
行データを後から追加しようとするとエラーとなります。
DataRow errorRow = table.NewRow(); errorRow[idColumn] = 100; errorRow[nameColumn] = DbNull.Value; // エラー:Nameの値を指定していない。(not null制約) table.Rows.Add(errorRow); errorRow[idColumn] = 1; errorRow[nameColumn] = "Dummy Value"; // エラー:Idの値が重複している(Primary Key制約) table.Rows.Add(errorRow); errorRow[idColumn] = 100; errorRow[nameColumn] = "gsf_zero1"; errorRow[ageColumn] = 28; // エラー:NameとAgeの組み合わせが既に存在している。(Unique制約) table.Rows.Add(errorRow)