ファイル操作
|
|
|
- ひろみ ひがき
- 7 years ago
- Views:
Transcription
1 データセット DataSet クラス データのメモリ内キャッシュを表す 名前空間 :System.Data アセンブリ :System.Data(system.data.dll 内 ) 解説 データソースから取得されたデータのメモリ内キャッシュで有る DataSet は ADO.NET アーキテクチャの主要コンポーネントで有る DataSet は DataRelation オブジェクトと相互に関連付ける事が出来る DataTable オブジェクトのコレクションで構成される UniqueConstraint オブジェクトと ForeignKeyConstraint オブジェクトを使用して DataSet 内でデータの整合性を適用する事も出来る DataSet オブジェクトの使用の詳細に付いては ADO.NET での DataSet の使用 を参照され度い DataTable オブジェクトにはデータを格納出来るのに対して DataRelationCollection を使用するとテーブルの階層構造内を移動出来る テーブルは Tables プロパティを使用してアクセス出来る DataTableCollection に格納される DataTable オブジェクトにアクセスする時は 条件付きで大文字と小文字が区別される事に注意され度い 例えば mydatatable と謂う名前の DataTable と Mydatatable と謂う名前のテーブルが有る場合は 此の 2 つのーブルの孰れかを検索する文字列は大文字と小文字を区別すると看做される 但し mydatatable と謂う名前は存在するが Mydatatable と謂う名前が存在しない場合は 検索文字列は大文字と小文字を区別しないと看做される DataTable オブジェクトの使用の詳細に付いては DataTable の作成 を参照され度い DataSet では データとスキーマを XML ドキュメントとして読み取ったり 書き込んだり出来る 読み込んだデータとスキーマは HTTP で転送出来 XML 対応の総てのプラットフォーム 及び アプリケーションで使用出来る スキーマを XML スキーマと仕て保存するには WriteXmlSchema メソッドを使用する スキーマとデータの両方を保存するには WriteXml メソッドを使用する スキーマとデータの両方を含む XML ドキュメントを読み取るには ReadXml メソッドを使用する 通常の多階層の実装で DataSet を作成 更新し 次に元のデータを更新するステップを次に示す 1.DataAdapter を使用して DataSet 内に DataTable を作成し 各テーブルにデータソースのデータを格納する 2.DataRow オブジェクトを追加 更新 又は 削除して 個別の DataTable オブジェクト内のデータを変更する 3.GetChanges メソッドを呼び出して データへの変更丈を格納する 2 つ目の DataSet を作成する 4. 此の 2 つ目の DataSet を引数と仕て渡して DataAdapter の Update メソッドを呼び出す 5.Merge を呼び出して 2 つ目の DataSet に格納された変更を最初のデータセットにマージする 6.DataSet で AcceptChanges を呼び出す 変更をキャンセルするには RejectChanges を呼び出す -1-
2 パブリックプロパティ 名前 説明 CaseSensitive DataTable オブジェクト内の文字列比較で大文字と小文字を区別するか 何うかを示す値を取得 設定する Container コンポーネントを格納するコンテナを取得する DataSetName 現在の DataSet の名前を取得 設定する DefaultViewManager カスタム DataViewManager を使用してフィルタ処理 検索 移動の各 操作を行う事が出来る DataSet に格納されて居るデータのカスタムビ ューを取得する DesignMode コンポーネントが現在デザインモードか何うかを示す値を取得する EnforceConstraints 更新操作を試みた時に操作が制約規則に従って居るか何うかを示す値 を取得 設定する ExtendedProperties DataSet に関連付けられて居るカスタマイズされたユーザー情報のコレ クションを取得する HasErrors 此の DataSet 内の DataTable オブジェクトの孰れかにエラーが有るか 何うかを示す値を取得する IsInitialized DataSet が初期化されて居るか何うかを示す値を取得する Locale テーブル内の文字列の比較に使用するロケール情報を取得 設定する Namespace DataSet の名前空間を取得 設定する Prefix DataSet の名前空間に別名を付ける XML プリフィックスを取得 設定 する Relations テーブルをリンクし 親テーブルから子テーブルへ移動出来る様にする リレーションシップのコレクションを取得する RemotingFormat リモート処理中に使用される DataSet の SerializationFormat を取得 設定する SchemaSerializationMode DataSet の SchemaSerializationMode を取得 設定する Site DataSet の System.ComponentModel.ISite を取得 設定する Tables DataSet に格納されて居るテーブルのコレクションを取得する プロテクトプロパティ Events 名前 説明コンポーネントに結び付けられて居るイベントハンドラのリストを取得する パブリックメソッド 名前 AcceptChanges BeginInit Clear Clone Copy CreateDataReader Dispose 説明此の DataSet の読み込み 又は 前回の AcceptChanges の呼出以降に此のデータセットに対して行われた総ての変更をコミットする フォームや別のコンポーネントで使用する DataSet の初期化を開始する ( 初期化は実行時に発生する ) 総てのテーブル内の総ての行を削除して データの DataSet を消去する 総ての DataTable スキーマ リレーションシップ 及び 制約を含め DataSet の構造体をコピーする ( データのコピーは行わない ) 此の DataSet の構造体丈でなくデータもコピーする DataTable 毎に 1 つの結果セットを含む DataTableReader を返す ( 順序は Tables コレクション内のテーブルでの出現順序と同じで有る ) MarshalByValueComponent に依って使用されて居るリソースを解放する -2-
3 EndInit Equals GetChanges GetDataSetSchema GetHashCode GetObjectData GetService GetType GetXml GetXmlSchema HasChanges InferXmlSchema Load Merge ReadXml ReadXmlSchema ReferenceEquals RejectChanges Reset ToString WriteXml WriteXmlSchema フォーム又は別のコンポーネントで使用する DataSet の初期化を終了する ( 初期化は実行時に発生する ) 2 つの Object インスタンスが等しいか何うかを判断する 前回 DataSet を読み取るか AcceptChanges を呼び出した以降に此のデータセットに対して行われた総ての変更が格納されて居る此のデータセットのコピーを取得する 特定の型のハッシュ関数と仕て機能する GetHashCode は ハッシュアルゴリズムや ハッシュテーブルの様なデータ構造での使用に適して居る DataSet をシリアル化する為に必要なデータをシリアル化情報オブジェクトに設定する IServiceProvider を実装して居るオブジェクトを取得する 現在のインスタンスの Type を取得する DataSet に格納されて居るデータの XML 表現を返す DataSet に格納されて居るデータの XML 表現の XML スキーマを返す DataSet に新しい行 削除された行 変更された行等の変更が有るか何うかを示す値を取得する XML スキーマを DataSet に適用する 指定された IDataReader を使用し DataSet にデータソースからの値を設定する 指定した DataSet か DataTable 又は DataRow オブジェクトの配列を現在の DataSet 又は DataTable にマージする XML スキーマとデータを DataSet に読み込む XML スキーマを DataSet に読み込む 指定した複数の Object インスタンスが同一か何うかを判断する 此の DataSet を作成するか 前回 DataSet.AcceptChanges を呼び出した以降に此のデータセットに対して行われた総ての変更をロールバックする DataSet を元の状態にリセットする ( サブクラスが Reset をオーバーライドして DataSet を元の状態に戻す必要が有る ) Component の名前を格納して居る String を返す 此のメソッドはオーバーライド出来ません (MarshalByValueComponent から継承される ) DataSet から XML データを書き込む オプションでスキーマも書き込む事が出来る DataSet 構造体を XML スキーマと仕て書き込む プロテクトメソッド 名前説明 DetermineSchemaSerializationMode DataSet の SchemaSerializationMode を判別する Dispose MarshalByValueComponent に依って使用されて居るリソースを解放する (MarshalByValueComponent から継承される ) Finalize [To be supplied.] (MarshalByValueComponent から継承される ) GetSchemaSerializable GetSerializationData InitializeDerivedDataSet IsBinarySerialized MemberwiseClone 現在の Object の簡易コピーを作成する (Object から継承される ) -3-
4 OnPropertyChanging OnRemoveRelation OnRemoveTable RaisePropertyChanging ReadXmlSerializable ShouldSerializeRelations ShouldSerializeTables OnPropertyChanging イベントを発生させます DataTable から DataRelation オブジェクトが削除された時に発生する DataSet から DataTable が削除された時に発生する 指定した DataSet プロパティが此れから変更されると謂う通知を送信する Relations プロパティを永続化する必要が有るか何うかを示す値を取得する Tables プロパティを永続化する必要が有るか何うかを示す値を取得する 使用例 幾つかのメソッドを組み合わせて DataSet を作成した後で Northwind データベースのデータを読み込む例を次に示す Option Explicit On Option Strict On Visual basic Imports System.Data Imports system.data.sqlclient Public Class NorthwindDataSet Public Shared Sub Main() Dim connectionstring As String = GetConnectionString( ) ConnectToData(connectionString) End Sub Private Shared Sub ConnectToData( ByVal connectionstring As String) ' Create a SqlConnection to the Northwind database. Using connection As SqlConnection = New SqlConnection( connectionstring) ' Create a SqlDataAdapter for the Suppliers table. Dim suppliersadapter As SqlDataAdapter = New SqlDataAdapter( ) ' A table mapping names the DataTable. suppliersadapter.tablemappings.add("table", "Suppliers") ' Open the connection. connection.open( ) Console.WriteLine("The SqlConnection is open.") ' Create a SqlCommand to retrieve Suppliers data. Dim supplierscommand As SqlCommand = New SqlCommand( _ "SELECT SupplierID, CompanyName FROM dbo.suppliers;", connection) supplierscommand.commandtype = CommandType.Text ' Set the SqlDataAdapter's SelectCommand. suppliersadapter.selectcommand = supplierscommand ' Fill the DataSet. Dim dataset As DataSet = New DataSet("Suppliers") suppliersadapter.fill(dataset) -4-
5 ' Create a second SqlDataAdapter and SqlCommand to get ' the Products table, a child table of Suppliers. Dim productsadapter As SqlDataAdapter = New SqlDataAdapter( ) productsadapter.tablemappings.add("table", "Products") Dim productscommand As SqlCommand = New SqlCommand( _ "SELECT ProductID, SupplierID FROM dbo.products;", connection) productsadapter.selectcommand = productscommand ' Fill the DataSet. productsadapter.fill(dataset) ' Close the connection. connection.close( ) Console.WriteLine("The SqlConnection is closed.") ' Create a DataRelation to link the two tables based on the SupplierID. Dim parentcolumn As DataColumn = _ dataset.tables("suppliers").columns("supplierid") Dim childcolumn As DataColumn = _ dataset.tables("products").columns("supplierid") Dim relation As DataRelation = New _ System.Data.DataRelation("SuppliersProducts", parentcolumn, childcolumn) dataset.relations.add(relation) Console.WriteLine( "The 0 DataRelation has been created.", relation.relationname) End Using End Sub Private Shared Function GetConnectionString( ) As String ' To avoid storing the connection string in your code, ' you can retrieve it from a configuration file. Return "Data Source=(local);Initial Catalog=Northwind; Integrated Security=SSPI;" End Function End Class using System; using System.Data; using System.Data.SqlClient; namespace Microsoft.AdoNet.DataSetDemo class NorthwindDataSet static void Main( ) string connectionstring = GetConnectionString( ); ConnectToData(connectionString); private static void ConnectToData(string connectionstring) //Create a SqlConnection to the Northwind database. using (SqlConnection connection = new SqlConnection(connectionString)) -5-
6 //Create a SqlDataAdapter for the Suppliers table. SqlDataAdapter adapter = new SqlDataAdapter( ); // A table mapping names the DataTable. adapter.tablemappings.add("table", "Suppliers"); // Open the connection. connection.open( ); Console.WriteLine("The SqlConnection is open."); // Create a SqlCommand to retrieve Suppliers data. SqlCommand command = new SqlCommand( "SELECT SupplierID, CompanyName FROM dbo.suppliers;",connection); command.commandtype = CommandType.Text; // Set the SqlDataAdapter's SelectCommand. adapter.selectcommand = command; // Fill the DataSet. DataSet dataset = new DataSet("Suppliers"); adapter.fill(dataset); // Create a second Adapter and Command to get // the Products table, a child table of Suppliers. SqlDataAdapter productsadapter = new SqlDataAdapter( ); productsadapter.tablemappings.add("table", "Products"); SqlCommand productscommand = new SqlCommand( "SELECT ProductID, SupplierID FROM dbo.products;",connection); productsadapter.selectcommand = productscommand; // Fill the DataSet. productsadapter.fill(dataset); // Close the connection. connection.close( ); Console.WriteLine("The SqlConnection is closed."); // Create a DataRelation to link the two tables based on the SupplierID. DataColumn parentcolumn = dataset.tables["suppliers"].columns["supplierid"]; DataColumn childcolumn = dataset.tables["products"].columns["supplierid"]; DataRelation relation = new System.Data.DataRelation("SuppliersProducts", parentcolumn, childcolumn); dataset.relations.add(relation); Console.WriteLine("The 0 DataRelation has been created.",relation.relationname); static private string GetConnectionString( ) // To avoid storing the connection string in your code, // you can retrieve it from a configuration file. return "Data Source=(local);Initial Catalog=Northwind; Integrated Security=SSPI"; -6-
7 DataSet クラスの概要 DataSet オブジェクトは ADO.NET で非接続型分散データシナリオをサポートする上で中心的な役割を果たす DataSet は メモリ内に常駐するデータ表現で有り データソースの違いに拘らず 一貫性の有るリレーショナルプログラミングモデルを提供する 複数の異なるデータソースや XML データと組み合わせて使用出来 アプリケーションに取ってローカルなデータの管理にも使用出来る DataSet は 関連テーブル 制約 及び テーブル間のリレーションシップを含む完全なデータセットを表現する 次の図に示すのが DataSet オブジェクトモデルで有る DataSet オブジェクトモデル 1 つの DataSet に含まれるメソッドとオブジェクトは リレーショナルデータベースモデルに含まれるメソッドやオブジェクトと整合性が有る DataSet は 其の内容を XML と仕て永続化 及び 再読み込みしたり 其のスキーマを XML スキーマ定義言語 (XSD) スキーマと仕て永続化 及び 再読み込みしたり出来る 詳細に付いては DataSet での XML の使用 を参照され度い DataTableCollection ADO.NET の DataSet には DataTable オブジェクトに依って表現される 0 個以上のテーブルのコレクションが含まれる DataTableCollection には 1 つの DataSet に属する総ての DataTable オブジェクトが含まれて居る DataTable は System.Data 名前空間で定義され メモリ常駐データの 1 つのテーブルを表現する 此のテーブルには 共にテーブルのスキーマを定義する DataColumnCollection で表現される列と ConstraintCollection で表現される制約のコレクションが含まれる DataTable には テーブル内のデータが格納された DataRowCollection で表現される行のコレクションも含まれる DataRow には 行に格納された値の変更を識別出来る様に 行の現在の状態と共に 行の現在のバージョンと元のバージョンの両方が保持される -7-
8 DataRelationCollection DataSet の DataRelationCollection オブジェクトにはリレーションシップが含まれる DataRelation オブジェクトで表現されるリレーションシップは 或る DataTable の行を別の DataTable の行に関連付ける リレーションシップは リレーショナルデータベースの主キー列と外部キー列の間に存在する結合パスに似て居る DataRelation は 1 つの DataSet が含む 2 つのテーブルの間で 一致する列を識別する リレーションシップを使用すると DataSet 内部の 或るテーブルと別のテーブルを行き来する事が出来る DataRelation で必須とされる要素は リレーションシップの名前 関連付けるテーブルの名前 及び 各テーブル内で関連付けられる列で有る DataColumn オブジェクトの配列をキー列と仕て指定する事に依って テーブル毎に複数の列を使用してリレーションシップを構築出来る DataRelationCollection にリレーションシップを追加する時は 関連列の値が変更された時に整合性制約を適用する為に オプションで UniqueKeyConstraint 及び ForeignKeyConstraint を追加出来る ExtendedProperties DataSet DataTable 及び DataColumn には 総て ExtendedProperties プロパティが有る ExtendedProperties は PropertyCollection で有り 此処には 結果セットの生成に使われた SELECT ステートメントやデータが生成された時刻等 独自の情報を格納出来る ExtendedProperties コレクションは DataSet のスキーマ情報と共に永続化される DataSet の作成 DataSet のインスタンスを作成するには DataSet のコンストラクタを呼び出す 必要に応じて 引数 name を指定する 名前を指定しない場合 DataSet の名前は NewDataSet に設定される 亦 既存の DataSet に基づいて新しい DataSet を作成する事も出来る 既存の DataSet の正確なコピーを新しい DataSet と仕て作成出来るのは リレーショナル構造やスキーマはコピーするけれども既存の DataSet からのデータは含まない DataSet のクローン 又は GetChanges メソッドを使用して既存の DataSet から変更された行丈を含む DataSet のサブセットの孰れかで有る 詳細に付いては DataSet の内容のコピー を参照され度い DataSet のインスタンスの作成方法を示すコード例を次に示す Dim customerorders As DataSet = New DataSet("CustomerOrders") DataSet customerorders = new DataSet("CustomerOrders"); DataSet への DataTable の追加 ADO.NET を使用して DataTable オブジェクトを作成し 其のオブジェクトを既存の DataSet に追加出来る PrimaryKey プロパティと Unique プロパティを使用する事で DataTable の制約情報を設定出来る 例 DataSet を構築し DataSet に新しい DataTable オブジェクトを追加してから 3 つの DataColumn オブジェクトを其のテーブルに追加する例を次に示す コードの最後では 1 つの列が主キーの列と仕て設定されて居る -8-
9 大文字と小文字の区別 大文字と小文字の区別が異なれば DataSet に存在する 2 つ以上のテーブルやリレーションが同じ名前を持つ事が出来る 此の場合 名前を使用してテーブルとリレーションを参照する際に大文字と小文字が区別される 例えば DataSet dataset に Table1 と table1 のテーブルが有る場合 Table1 を参照するには dataset.tables["table1"] table1 を参照するには dataset.tables ["table1"] と名前を指定する 此の孰れかのテーブルの参照に dataset.tables ["TABLE1"] と指定すると 例外が発生する 特定の名前を持つテーブルやリレーションが 1 つ而巳の場合 大文字と小文字は区別されない 例えば DataSet に Table1 しか存在しない場合は dataset.tables["table1"] を使用して其のテーブルを参照出来る メモ : 此の動作は DataSet の CaseSensitive プロパティの影響を受けない CaseSensitive プロパティは DataSet 内のデータに適用され 並替 検索 フィルタ処理 制約の適用等に影響を及ぼす 名前空間のサポート 以前のバージョンの ADO.NET では 異なる名前空間に存在して居るテーブルで有っても 2 つのテーブルが同じ名前を持つ事は出来なかった ADO.NET 2.0 には 此の制限は無い 従って DataSet に Namespace プロパティ値が異なり TableName プロパティ値が一致する 2 つのテーブルが存在しても問題無い テーブル間のリレーションシップの追加 複数の DataTable オブジェクトを含む DataSet では DataRelation オブジェクトを使用して 1 つのテーブルを別のテーブルに関連付けたり テーブル間を移動したり 関連付けたテーブルから子や親の行を戻したり出来る DataRelation の作成に必要な引数は 作成する DataRelation の名前 及び 其のリレーションシップで親子の列と成る列への 1 つ以上の DataColumn 参照の配列で有る DataRelation の作成後 DataRelation を使用してテーブル間の移動や値の取得を行う事が出来る DataSet への DataRelation の追加は 既定では UniqueConstraint が親テーブルに ForeignKeyConstraint が子テーブルに追加される 上記の既定の制約の詳細に付いては テーブルへの制約の追加 を参照され度い DataSet に有る 2 つの DataTable オブジェクトを使用して DataRelation を作成するコード例を次に示す 各 DataTable には 2 つの DataTable オブジェクト間のリンクと成る CustID と謂う名前の列が有る 例では 単一の DataRelation が DataSet の Relations コレクションに追加される 例に有る最初の引数には 作成する DataRelation の名前を指定する 2 番目の引数に依って親の DataColumn が 3 番目の引数に依って子の DataColumn が設定される customerorders.relations.add("custorders", _ customerorders.tables("customers").columns("custid"), _ customerorders.tables("orders").columns("custid")) customerorders.relations.add("custorders", customerorders.tables["customers"].columns["custid"], customerorders.tables["orders"].columns["custid"]); DataRelation には 入れ子に成ったプロパティも有る true に設定すると WriteXml を使用して XML 要素と仕て書き込む時に 親テーブルの関連付けられた行の中で子テーブルの行が入れ子に成る 詳細に付いては DataSet での XML の使用 を参照され度い -9-
10 テーブル間のリレーションシップの移動 DataRelation の主な機能の 1 つは DataSet の 1 つの DataTable から別の DataTable を移動出来る事で有る 此の参照に依り 関連付けられた DataTable から単一の DataRow を指定すると 1 つの DataTable 内の関連する DataRow オブジェクトを総て取得出来る 例えば 顧客のテーブルとオーダーのテーブル間に DataRelation を確立すると GetChildRows を使用して特定の顧客行のオーダー行を総て取得出来る DataSet の Customers テーブルと Orders テーブル間の DataRelation を作成し 各顧客の総てのオーダーを返すコード例を次に示す 上記の例に基づいて 4 つのテーブルを相互に関連付け 其のテーブルのリレーションシップ間を移動する例を次に示す 上記の例に示す様に CustomerID は Customers テーブルを Orders テーブルに関連付ける Customers テーブルに有る各顧客に対しては Orders テーブルに有る総ての子の行が確定され 該当する顧客のオーダー数と其の OrderID の値が返される 展開された例では OrderDetails テーブルと Products テーブルからも値が返される 各顧客のオーダーに対しては オーダーされた製品と数量を示す為に OrderID を使用して Orders テーブルが OrderDetails テーブルに関連付けられる OrderDetails テーブルに含まれて居るのは オーダーされた製品の ProductID 丈で有る為 ProductID を使用して OrderDetails を Products に関連付けて ProductName を返す 此のリレーションでは Products テーブルが親と成り OrderDetails テーブルが子と成る 其の結果 OrderDetails テーブルを順次処理すると GetParentRow が呼び出され 関連付けられた ProductName の値を取得する DataRelation が Customers テーブルと Orders テーブルに対して作成された場合には createconstraints フラグには値が指定されない ( 既定値は true) 此れは Orders テーブルに有る総ての行に対して親の Customers テーブルに有る CustomerID の値が設定されて居る為で有る Orders テーブルに Customers テーブルに存在しない CustomerID が存在する場合 ForeignKeyConstraint は例外をスローする 親の列に含まれて居ない値が子の列に含まれる場合 DataRelation の追加時に createconstraints フラグが false に設定される 例では Orders テーブルと OrderDetails テーブル間の DataRelation に対して createconstraints フラグが false に設定されて居る 此の為 此のアプリケーションでは OrderDetails テーブルから総てのレコードを返し 実行時に例外を生成せずに Orders テーブルからレコードのサブセット丈を返す事が出来る 展開された例では 次の形式で出力が生成される Customer ID: NORTS Order ID: Order Date: 4/24/ :00:00 AM Product: Filo Mix Quantity: 6 Product: Raclette Courdavault Quantity: 4 Product: Outback Lager Quantity: 6 Order ID: Order Date: 4/29/ :00:00 AM Product: Outback Lager Quantity: 3 Orders テーブルのレコードのサブセット丈と共に OrderDetails テーブルと Products テーブルからの値が返された場合に展開された例を次のコード例に示す -10-
11 Dim customerordersrelation As DataRelation = _ customerorders.relations.add("custorders", _ customerorders.tables("customers").columns("customerid"), _ customerorders.tables("orders").columns("customerid")) Dim orderdetailrelation As DataRelation = _ customerorders.relations.add("orderdetail", _ customerorders.tables("orders").columns("orderid"), _ customerorders.tables("orderdetails").columns("orderid"), False) Dim orderproductrelation As DataRelation = _ customerorders.relations.add("orderproducts", _ customerorders.tables("products").columns("productid"), _ customerorders.tables("orderdetails").columns("productid")) Dim custrow, orderrow, detailrow As DataRow For Each custrow In customerorders.tables("customers").rows Console.WriteLine("Customer ID:" & custrow("customerid").tostring( )) For Each orderrow In custrow.getchildrows(customerordersrelation) Console.WriteLine("Order ID: " & orderrow("orderid").tostring( )) Console.WriteLine(vbTab & "Order Date: " & orderrow("orderdate").tostring( )) For Each detailrow In orderrow.getchildrows(orderdetailrelation) Console.WriteLine(vbTab & " Product: " & _ detailrow.getparentrow(orderproductrelation) ("ProductName").ToString( )) Console.WriteLine(vbTab & "Quantity: " & detailrow("quantity").tostring( )) Next Next Next DataRelation customerordersrelation = customerorders.relations.add("custorders", customerorders.tables["customers"].columns["customerid"], customerorders.tables["orders"].columns["customerid"]); DataRelation orderdetailrelation = customerorders.relations.add("orderdetail", customerorders.tables["orders"].columns["orderid"], customerorders.tables["orderdetails"].columns["orderid"], false); DataRelation orderproductrelation = customerorders.relations.add("orderproducts", customerorders.tables["products"].columns["productid"], customerorders.tables["orderdetails"].columns["productid"]); foreach (DataRow custrow in customerorders.tables["customers"].rows) Console.WriteLine("Customer ID: " + custrow["customerid"]); foreach (DataRow orderrow in custrow.getchildrows(customerordersrelation)) Console.WriteLine("Order ID: " + orderrow["orderid"]); Console.WriteLine(" torder Date: " + orderrow["orderdate"]); foreach (DataRow detailrow in orderrow.getchildrows(orderdetailrelation)) Console.WriteLine(" t Product: " + detailrow.getparentrow(orderproductrelation)["productname"]); Console.WriteLine(" t Quantity: " + detailrow["quantity"]); -11-
12 既存のデータを含む DataSet の使用 DataSet は データソースに依存しないデータに対するメモリ内のリレーショナル形式で有る 但し.NET Framework データプロバイダで使用する場合には DataSet はデータソース内の既存データと共に使用出来る.NET Framework データプロバイダでは DataAdapter を使用してデータソースのデータに加えた変更を解決する丈でなく DataSet にデータやスキーマの情報を格納する DataSet の読み込みや データソースのデータに加えた変更の解決の詳細に付いては 次の資料を参照され度い DataAdapter からの DataSet の読み込み 此の資料では データソースのデータを含む DataSet を読み込む方法に付いて説明する DataAdapter に依るデータソースの更新 此の資料では DataSet のデータに加えた変更を解決してデータソースに戻る方法に付いて説明する DataSet への既存の制約の追加 此の資料では データソースの主キー情報を含む DataSet を設定する方法に付いて説明する DataAdapter に依るパラメータの使用 及び パラメータと戻り値の指定 此等の資料では DataSet に有るテーブルの列をデータソースで実行されたコマンドの入力 及び 出力パラメータに関連付ける方法に付いて説明する DataSet では 既存の XML データの読み取りや書き込みを行う事も出来る 詳細に付いては DataSet での XML の使用 を参照され度い DataAdapter からの DataSet の読み込み ADO.NET の DataSet は データソースに依存しない一貫したリレーショナルプログラミングモデルを提供するメモリ常駐型のデータ表現で有る DataSet はテーブル 制約 及び テーブル間のリレーションシップを含む完全なデータのセットを表す DataSet はデータソースとは独立して居る為 DataSet には 其のアプリケーションに固有のデータと複数のデータソースからのデータを含める事が出来る 既存のデータソースとの対話は DataAdapter に依って制御される DataAdapter の SelectCommand プロパティは データソースからデータを取得する Command オブジェクトで有る DataAdapter の InsertCommand UpdateCommand DeleteCommand の各プロパティは DataSet のデータに対して行われた変更に基づいてデータソースのデータ更新を管理する Command オブジェクトで有る 此等のプロパティに付いては DataAdapter に依るデータソースの更新 で更に詳しく説明する DataAdapter の Fill メソッドは DataAdapter の SelectCommand の結果を使用して DataSet を設定する為に使用する Fill は 自らの引数と仕て 設定対象で有る DataSet と DataTable オブジェクト ( 詰まり SelectCommand が返した行を格納して居る DataTable の名前 ) を受け取る Fill メソッドは DataReader オブジェクトを暗黙的に使用して DataSet 内でテーブルを作成する為の列の名前と型 及び DataSet 内のテーブルの行を設定する為のデータを返す テーブルと列は 存在しない場合に丈作成される 既に存在する場合は Fill は既存の DataSet スキーマを使用する 列の型は.NET Framework データプロバイダのデータ型から.NET Framework のデータ型への変換 の表に基づき.NET Framework の型と仕て作成される データソースに主キーが存在し DataAdapter.MissingSchemaAction が MissingSchemaAction.AddWithKey に設定されて居る場合丈 主キーが作成されるが 其れ以外の場合は主キーは作成されない Fill はテーブルに主キーが有る事が解ると 主キー列の値がデータソースから返された主キー列の値と一致する行に付いて データソース -12-
13 から返されたデータで DataSet 内のデータを上書きする 主キーが見付からない場合は DataSet のテーブルの末尾にデータを追加する Fill は DataSet にデータを読み込む時に存在する総てのマッピングを使用する ( DataTable と DataColumn のマップの設定 を参照され度い ) メモ :SelectCommand が OUTER JOIN の結果を返す場合 DataAdapter は 生成される DataTable に PrimaryKey 値を設定しない 開発者が PrimaryKey を定義して 重複行が正しく解決される様にする必要が有る 詳細に付いては テーブルの主キーの定義 を参照され度い Microsoft SQL Server Northwind データベースへの SqlConnection を使用し DataSet 内の DataTable に顧客リストを読み込む SqlDataAdapter のインスタンスを作成するコード例を次に示す SqlDataAdapter コンストラクタに渡される SQL ステートメントと SqlConnection 引数は SqlDataAdapter の SelectCommand プロパティを作成する為に使用される ' Assumes that connection is a valid SqlConnection object. Dim querystring As String = "SELECT CustomerID, CompanyName FROM dbo.customers" Dim adapter As SqlDataAdapter = New SqlDataAdapter( querystring, connection) Dim customers As DataSet = New DataSet adapter.fill(customers, "Customers") // Assumes that connection is a valid SqlConnection object. string querystring = "SELECT CustomerID, CompanyName FROM dbo.customers"; SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection); DataSet customers = new DataSet( ); adapter.fill(customers, "Customers"); メモ : 此のサンプルコードでは Connection の開始と終了を明示的に行って居ない Fill メソッドは 接続が未だ開いて居ない事を認識すると DataAdapter が使用して居る Connection を暗黙的に開く Fill が接続を開いた場合は Fill の終了時に Fill が接続を終了する 此れに依り Fill や Update 等の単一の操作を扱う場合にコードを簡略化出来る 此れに対し 開いて居る接続を必要とする複数の操作を実行する場合は Connection の Open メソッドを明示的に呼び出し データソースに対する操作の実行後に Connection の Close メソッドを呼び出す事でアプリケーションのパフォーマンスを改善出来る リソースを解放して他のクライアントアプリケーションが使用出来る様にする為に データソースへの接続を開いた儘にする時間は最小限にする事を推奨する 複数結果セット DataAdapter は複数の結果セットを検出すると DataSet に複数のテーブルを作成する 此等のテーブルには Table0 の様に Table で始まるインクリメンタル既定名 TableN が割り当てられる テーブル名を引数と仕て Fill メソッドに渡すと TableName0 を表す TableName で始まるインクリメンタル既定名 TableNameN が割り当てられる 複数の DataAdapter からの DataSet の読み込み 1 つの DataSet で 任意の数の DataAdapter オブジェクトを使用出来る 夫々れの DataAdapter で 1 つ以上の DataTable オブジェクトにデータを格納し 関連するデータソースに更新を反映させる事が出来る DataSet に対して DataRelation オブジェクトや Constraint オブジェクトを部分的に追加出来る為 開発者は複数の異なるデータソースから取得したデータを関連付ける事が出来る 例えば Microsoft SQL Server データベース OLE DB を通じて公開される IBM DB2 データベース 及び XML をストリーム転送するデータソースからのデータを DataSet に含める事が出来る 1 つ以上の DataAdapter オブジェクトを使用して 各データソースとの通信を行う事が出来る -13-
14 例 次のコード例では Microsoft SQL Server 2000 の Northwind データベースからの顧客リストと Microsoft Access 2000 に格納されて居る Northwind データベースからの注文リストを取得する データが格納されて居るテーブルが DataRelation に関連付けられ 顧客の一覧が各顧客の注文と共に表示される DataRelation オブジェクトの詳細に付いては テーブル間のリレーションシップの追加 及び テーブル間のリレーションシップの移動 を参照され度い ' Assumes that customerconnection is a valid SqlConnection object. ' Assumes that orderconnection is a valid OleDbConnection object. Dim custadapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT * FROM dbo.customers", customerconnection) Dim ordadapter As OleDbDataAdapter = New OleDbDataAdapter( _ "SELECT * FROM Orders", orderconnection) Dim customerorders As DataSet = New DataSet( ) custadapter.fill(customerorders, "Customers") ordadapter.fill(customerorders, "Orders") Dim relation As DataRelation = _ customerorders.relations.add("custorders", _ customerorders.tables("customers").columns("customerid"), _ customerorders.tables("orders").columns("customerid")) Dim prow, crow As DataRow For Each prow In customerorders.tables("customers").rows Console.WriteLine(pRow("CustomerID").ToString( )) For Each crow In prow.getchildrows(relation) Console.WriteLine(vbTab & crow("orderid").tostring( )) Next Next // Assumes that customerconnection is a valid SqlConnection object. // Assumes that orderconnection is a valid OleDbConnection object. SqlDataAdapter custadapter = new SqlDataAdapter( "SELECT * FROM dbo.customers", customerconnection); OleDbDataAdapter ordadapter = new OleDbDataAdapter( "SELECT * FROM Orders", orderconnection); DataSet customerorders = new DataSet( ); custadapter.fill(customerorders, "Customers"); ordadapter.fill(customerorders, "Orders"); DataRelation relation = customerorders.relations.add("custorders", customerorders.tables["customers"].columns["customerid"], customerorders.tables["orders"].columns["customerid"]); foreach (DataRow prow in customerorders.tables["customers"].rows) Console.WriteLine(pRow["CustomerID"]); foreach (DataRow crow in prow.getchildrows(relation)) Console.WriteLine(" t" + crow["orderid"]); -14-
15 SQL Server の 10 進数型 既定では DataSet は.NET Framework のデータ型を使用してデータを格納する 殆どのアプリケーションで 此等のデータ型を使用してデータソース情報を簡単に表示出来る 併し データソースのデータ型が SQL Server の 10 進数データ型や数値データ型の場合は 此の表現に依って問題が生じる場合が有る.NET Framework の decimal データ型の最大有効桁数は 28 桁で有るのに対し SQL Server の decimal データ型の有効桁数は 38 桁で有る Fill が動作して居る間に SqlDataAdapter が SQL Server の decimal フィールドの有効桁数が 28 文字を超えて居ると判断した場合 現在の行は DataTable に追加されない 其の場合は FillError イベントが発生する為 開発者は有効桁数の消失が発生して居ないか何うかを確認し 適切に対応出来る FillError イベントの詳細に付いては DataAdapter イベントの使用 を参照され度い SQL Server の decimal 値を取得するには SqlDataReader オブジェクトを使用し GetSqlDecimal メソッドを呼び出す事も出来る ADO.NET 2.0 では DataSet の System.Data.SqlTypes に対するサポート機能が強化されて居る 詳細に付いては SqlTypes と DataSet を参照され度い OLE DB のチャプタ 階層構造の行セット 詰まり チャプタ (OLE DB では DBTYPE_HCHAPTER 型 ADO では adchapter 型 ) を使用して DataSet の内容を格納出来る OleDbDataAdapter が Fill が動作して居る間にチャプタ列を検出すると 其のチャプタ列の為の DataTable を作成し チャプタから取得した列と行を此のテーブルに格納する チャプタ列用に作成されたテーブルには 親テーブルの名前とチャプタ列の名前の両方を使用した ParentTableNameChapteredColumnName 形式の名前が割り当てられる DataSet にチャプタ列の名前と一致するテーブルが既に存在する場合は 現在のテーブルにチャプタデータが格納される 既存のテーブルにチャプタ内の列と一致する列が存在しない場合は 新しい列が追加される DataSet 内のテーブルにチャプタ列のデータを格納する前に 親テーブルと子テーブルの両方に 1 つの整数列を追加し 親列を自動インクリメントに設定し 両方のテーブルに追加された列を使用して DataRelation を作成すると 階層構造の行セットを形成して居る親テーブルと子テーブルの間にリレーションが作成される 追加されたリレーションには親テーブルの名前とチャプタ列の名前を使用した ParentTableNameChapterColumnName 形式の名前が割り当てられる 関連付けられた列は DataSet 丈に存在する 其のデータソースからの次の Fill 操作を実行すると 変更を既存の行にマージするのではなく テーブルに新しい行が追加される DataTable を受け取る DataAdapter.Fill オーバーロードを使用した場合は 其のテーブル丈にデータが格納される 自動インクリメント整数列は 引き続き其のテーブルに追加されるが 子テーブルの作成 子テーブルへのデータの格納 及び リレーションの作成は行われない MSDataShape プロバイダを使用して顧客リスト内の各顧客に対応するオーダー列を生成する例を次に示す チャプタ列を生成した後で 1 つの DataSet 内に其のデータを格納する Using connection As OleDbConnection = New OleDbConnection( _ "Provider=MSDataShape;Data Provider=SQLOLEDB;" & _ "Data Source=(local);Integrated " & _ "Security=SSPI;Initial Catalog=northwind") Dim adapter As OleDbDataAdapter = New OleDbDataAdapter( _ "SHAPE SELECT CustomerID, CompanyName FROM Customers " & _ "APPEND (SELECT CustomerID, OrderID FROM Orders AS Orders " & _ "RELATE CustomerID TO CustomerID)", connection) -15-
16 Dim customers As DataSet = New DataSet( ) adapter.fill(customers, "Customers") End Using using (OleDbConnection connection = new OleDbConnection( "Provider=MSDataShape;Data Provider=SQLOLEDB;" + "Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind")) OleDbDataAdapter adapter = new OleDbDataAdapter( "SHAPE SELECT CustomerID, CompanyName FROM Customers " + "APPEND (SELECT CustomerID, OrderID FROM Orders AS Orders " + "RELATE CustomerID TO CustomerID)", connection); DataSet customers = new DataSet( ); adapter.fill(customers, "Customers"); Fill 操作が完了すると DataSet に Customers と CustomersOrders の 2 つのテーブルが格納される CustomersOrders はチャプタ列を表す Orders と謂う列が Customers テーブルに追加され CustomersOrders と謂う列が CustomersOrders テーブルに追加される Customers テーブルの Orders 列は 自動インクリメントに設定される 親テーブルで有る Customers テーブルに追加された列を使用して CustomersOrders と謂う DataRelation が作成される サンプル結果の一部を次の表に示す TableName:Customers CustomerID CompanyName Orders ALFKI Alfreds Futterkiste 0 ANATR Ana Trujillo Emparedados y helados 1 TableName:CustomersOrders CustomerID OrderID CustomersOrders ALFKI ALFKI ANATR ANATR DataAdapter に依るデータソースの更新 DataAdapter の Update メソッドを呼び出して 変更を DataSet からデータソースに反映する Update メソッドは Fill メソッドと同様に 引数と仕て DataSet のインスタンス 及び オプションの DataTable オブジェクト 又は DataTable 名を受け取る DataSet のインスタンスは 行われた変更点を格納する DataSet で有る DataTable は 変更点の取得元のテーブルで有る Update メソッドを呼び出すと DataAdapter は 既に加えられた変更を解析し 適切なコマンド (INSERT UPDATE 又は DELETE) を実行する DataAdapter は DataRow へ加えられた変更を検出すると InsertCommand UpdateCommand 又は DeleteCommand を使用して其の変更を処理する 其の結果 デザイン時にコマンド構文を指定し 可能な場合はストアドプロシージャを使用する事に依り ADO.NET アプリケーションのパフォーマンスを最適化出来る コマンドは Update を呼び出す前に明示的に設定する必要が有る Update を呼び出し 其の更新に関連する適切なコマンドが存在しない場合 ( 例えば 削除済みの行に関連する DeleteCommand が存在しない場合 ) は 例外がスローされる -16-
17 Command パラメータを使用して DataSet 内の各変更行に対する SQL ステートメントやストアドプロシージャに入力値と出力値を指定出来る 詳細に付いては DataAdapter に依るパラメータの使用 を参照され度い DataTable を単一データベーステーブルに割り当てたり 単一データベースから生成する場合は DbCommandBuilder オブジェクトを利用して自動的に DataAdapter の DeleteCommand InsertCommand 及び UpdateCommand を生成出来る 詳細に付いては コマンドの自動生成 を参照され度い Update メソッドは変更点を元のデータソースに反映させるが DataSet に最後にデータを格納した後 他のクライアントがデータソースのデータを変更した可能性も有る DataSet を現在のデータで更新するには DataAdapter と Fill メソッドを使用する 新しい行がテーブルに追加され 更新された情報が既存の行に取り込まれる Fill メソッドは DataSet の行と SelectCommand に依って返された行の主キーの値を調べて 新しい行が追加されたか 又は 既存の行が更新されたかを判断する Fill メソッドは SelectCommand に依って返された結果の行に一致する主キーの値を持つ DataSet の行を見付けた場合 SelectCommand に依って返された行の情報で既存の行を更新して 既存の行の RowState を Unchanged に設定する SelectCommand に依って返された行の主キーの値が DataSet の何の行の主キーの値にも一致しない場合 Fill メソッドは RowState が Unchanged の新しい行を追加する メモ :SelectCommand が OUTER JOIN の結果を返す場合 DataAdapter は 生成される DataTable に PrimaryKey 値を設定しない 自分で PrimaryKey を定義して 重複行が正しく反映される様にする必要が有る 詳細に付いては テーブルの主キーの定義 を参照され度い Update メソッド呼出時に発生する例外を処理するには 行更新エラーが発生した時に RowUpdated イベントを使用して応答するか ( DataAdapter イベントの使用 を参照 ) 又は Update メソッド呼出の前に DataAdapter.ContinueUpdateOnError を true に設定し 更新が完了した時点で特定の行の RowError プロパティに格納されて居るエラー情報に応答する ( 行のエラー情報の追加と読み取り を参照 ) メモ :DataSet DataTable 又は DataRow に対して AcceptChanges を呼び出すと DataRow の総ての Original 値が DataRow の Current 値で上書きされる 行を一意に識別するフィールド値が変更された場合は AcceptChanges 呼出の後 Original 値はデータソースの値と一致しなく成る 例 DataAdapter の UpdateCommand を明示的に設定して 変更済みの行に対して更新を実行する方法を次の例に示す UPDATE ステートメントの WHERE 句に指定したパラメータが SourceColumn の Original 値を使用する様に設定されて居る事に注意され度い Current 値が既に変更されて居る可能性 然して データソースの値と一致して居ない可能性が有る為 此の設定は重要で有る Original 値は データソースから DataTable にデータを取得する為に使用された値で有る ' Assumes connection is a valid SqlConnection. Dim adapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CategoryID, CategoryName FROM Categories", connection) adapter.updatecommand = New SqlCommand( _ "UPDATE Categories SET CategoryName " & _ "WHERE CategoryID connection) adapter.updatecommand.parameters.add( _ "@CategoryName", SqlDbType.NVarChar, 15, "CategoryName") Dim parameter As SqlParameter = adapter.updatecommand.parameters.add( _ "@CategoryID", SqlDbType.Int) -17-
18 parameter.sourcecolumn = "CategoryID" parameter.sourceversion = DataRowVersion.Original Dim dataset As DataSet = New DataSet adapter.fill(dataset, "Categories") Dim row As DataRow = dataset.tables("categories").rows(0) row("categoryname") = "New Category" adapter.update(dataset, "Categories") // Assumes connection is a valid SqlConnection. SqlDataAdapter dataadpater = new SqlDataAdapter( "SELECT CategoryID, CategoryName FROM Categories", connection); dataadpater.updatecommand = new SqlCommand( "UPDATE Categories SET CategoryName " + "WHERE CategoryID connection); dataadpater.updatecommand.parameters.add( "@CategoryName", SqlDbType.NVarChar, 15, "CategoryName"); SqlParameter parameter = dataadpater.updatecommand.parameters.add( "@CategoryID", SqlDbType.Int); parameter.sourcecolumn = "CategoryID"; parameter.sourceversion = DataRowVersion.Original; DataSet dataset = new DataSet( ); dataadpater.fill(dataset, "Categories"); DataRow row = dataset.tables["categories"].rows[0]; row ["CategoryName"] = "New Category"; dataadpater.update(dataset, "Categories"); AutoIncrement 列 データソースからのテーブルに自動インクリメント列が有る場合 DataSet の列に値を格納するには 自動インクリメント値をストアドプロシージャの出力パラメータと仕て返して其れをテーブルの列に割り当てるか 又は DataAdapter の RowUpdated イベントを使用する 此の例に付いては ID 値及び Autonumber 値の取得 を参照され度い 但し DataSet 内の値はデータソースの値と同期しなく成る為 予期しない動作を発生する場合が有る 例えば CustomerID と謂う自動インクリメント主キー列を持つテーブルが有るとする DataSet 内に新しい 2 人の顧客を追加した場合 此等の顧客は自動インクリメント CustomerId 値 1 及び 2 を受け取る 2 行目の顧客行が DataAdapter の Update メソッドに渡されると 新しく追加された行は データソースで自動インクリメント CustomerID 値 1 を受け取る 此れは DataSet 内の値 2 とは一致しない DataAdapter が DataSet の行に戻り値を設定すると 1 行目の顧客行が既に CustomerID 値と仕て 1 を持つ為 制約違反が発生する 此の様な動作を防ぐには データソースの自動インクリメント列 及び DataSet の自動インクリメント値を使用する時に AutoIncrementStep を -1 AutoIncrementSeed を 0 に設定して DataSet に列を作成し 同時に 1 から始まり正のステップ値でインクリメントする自動インクリメント ID 値がデータソースで生成される様にする 其の結果 DataSet では自動インクリメント値と仕て負の数値が生成される為 データソースで生成される正の自動インクリメント値と矛盾しなく成る 今 1 つの方法は 自 -18-
19 動インクリメント列の代わりに Guid 型の列を使用する事で有る Guid 値生成のアルゴリズムでは データソースで生成される Guid と同じ Guid が DataSet で生成される事は無い DataTable の列を定義する方法の詳細に付いては DataTable のスキーマの定義 を参照され度い 挿入 更新 削除の順序 通常の条件下では DataSet を使用して行う変更の順序をデータソースに送信する事が重要で有る 例えば 既存の行の主キーの値を更新し 其の新しい主キーの値で新しい行を追加する場合 更新は挿入の前に処理する必要が有る DataTable の Select メソッドを使用すると 特定の RowState を持つ行丈を参照する DataRow 配列を返す事が出来る 其の後で 返された DataRow 配列を DataAdapter の Update メソッドに渡して変更行を処理出来る 更新する行のサブセットを指定する事で 挿入 更新 及び 削除の処理順序を制御出来る 例 例えば次のコードでは テーブルの削除行を最初に処理し 次に更新行 最後に挿入行を処理する Dim table As DataTable = dataset.tables("customers") ' First process deletes. dataset.update(table.select(nothing, Nothing, DataViewRowState.Deleted)) ' Next process updates. adapter.update(table.select(nothing, Nothing, DataViewRowState.ModifiedCurrent)) ' Finally, process inserts. dataadpater.update(table.select(nothing, Nothing, DataViewRowState.Added)) DataTable table = dataset.tables["customers"]; // First process deletes. adapter.update(table.select(null, null, DataViewRowState.Deleted)); // Next process updates. adapter.update(table.select(null, null, DataViewRowState.ModifiedCurrent)); // Finally, process inserts. adapter.update(table.select(null, null, DataViewRowState.Added)); DataSet への既存の制約の追加 DataAdapter の Fill メソッドは DataSet にデータソースからのテーブルの列と行丈を格納する 制約は一般にデータソースで設定されるが 既定では Fill メソッドは DataSet にスキーマ情報を追加しない データソースからの既存の主キー制約情報を DataSet に設定するには DataAdapter の FillSchema メソッドを呼び出すか 又は Fill を呼び出す前に DataAdapter の MissingSchemaAction プロパティを AddWithKey に設定する 此れに依り データソースの主キー制約が DataSet の主キー制約に反映される 外部キー制約情報はインクルードされない為 テーブルへの制約の追加 で示す様に明示的に作成する必要が有る DataSet 内にデータを格納する前にスキーマ情報を追加すると 主キー制約が DataSet 内の DataTable -19-
20 オブジェクトにインクルードされる 其の結果 DataSet に対して格納を行う追加の呼出を行った時 其の主キー列情報を使用してデータソースから得られた新しい行と各 DataTable の現在の行を一致させ 各テーブルの現在のデータをデータソースのデータで上書きする スキーマ情報が無いと DataSet にデータソースからの新しい行が付け加えられ 重複行が発生する メモ : データソースの列を自動インクリメント列と仕て指定した場合は FillSchema メソッド (MissingSchemaAction を AddWithKey に設定した Fill メソッド ) が AutoIncrement プロパティを true に設定した DataColumn を作成する 但し AutoIncrementStep 値と AutoIncrementSeed 値は明示的に設定する必要が有る 自動インクリメント列の詳細に付いては AutoIncrement 列の作成 を参照され度い FillSchema の使用や MissingSchemaAction の設定を AddWithKey にする場合 データソースで主キー列情報を確認する為の追加の処理が必要に成る 此の追加の処理に依りパフォーマンスが低下する場合が有る デザイン時に主キー情報が解って居る場合は 最適のパフォーマンスを得る為に主キー列 ( 複数の場合も有る ) を明示的に指定する事を推奨する テーブルに関する主キー情報を明示的に設定する方法に付いては テーブルの主キーの定義 を参照され度い FillSchema を使用して DataSet にスキーマ情報を追加する方法を次のコード例に示す Dim custdataset As DataSet = New DataSet( ) custadapter.fillschema(custdataset, SchemaType.Source, "Customers") custadapter.fill(custdataset, "Customers") DataSet custdataset = new DataSet( ); custadapter.fillschema(custdataset, SchemaType.Source, "Customers"); custadapter.fill(custdataset, "Customers"); Fill メソッドの MissingSchemaAction.AddWithKey プロパティを使用してスキーマ情報を DataSet に追加する方法を次のコード例に示す Dim custdataset As DataSet = New DataSet( ) custadapter.missingschemaaction = MissingSchemaAction.AddWithKey custadapter.fill(custdataset, "Customers") DataSet custdataset = new DataSet( ); custadapter.missingschemaaction = MissingSchemaAction.AddWithKey; custadapter.fill(custdataset, "Customers"); 複数結果セット DataAdapter は SelectCommand から返された複数の結果セットを検出すると DataSet に複数のテーブルを作成する 此等のテーブルには 0 から始まるインクリメンタル既定名 TableN が割り当てられる 従って Table0 ではなく Table から始まる テーブル名が FillSchema メソッドに引数と仕て渡されると 0 からから始まるインクリメンタル名 TableNameN が割り当てられる 此処では TableName0 ではなく TableName から始まる メモ :OleDbDataAdapter オブジェクトの FillSchema メソッドが複数の結果セットを返すコマンドと -20-
21 仕て呼び出された場合は 最初の結果セットのスキーマ情報が返される OleDbDataAdapter を使用して複数の結果セットのスキーマ情報を返す時は Fill メソッドを呼び出す時に AddWithKey に設定した MissingSchemaAction を指定してスキーマ情報を取得する事を推奨する DataAdapter に依るパラメータの使用 DataAdapter は データソースからデータを取得したりデータソースのデータを更新したりする為に使用される 次の 4 つのプロパティを持って居る SelectCommand プロパティは データソースからデータを返す InsertCommand UpdateCommand 及び DeleteCommand の各プロパティは データソースの変更を管理する為に使用する SelectCommand プロパティは DataAdapter の Fill メソッドを呼び出す前に設定する必要が有る InsertCommand UpdateCommand DeleteCommand の各プロパティは DataAdapter の Update メソッドを呼び出す前に DataSet 内のデータに対して行われた変更に基づいて設定する必要が有る 例えば 行が追加された場合 InsertCommand は Update 呼出の前に設定されて居る必要が有る Update が挿入行 更新行 又は 削除行を処理して居る時 DataAdapter が夫々れの Command プロパティを使用して其のアクションを処理する 変更された行に付いての現在の情報が Parameters コレクションを通じて Command オブジェクトに渡される データソースの行を更新する時は 一意識別子を使用してテーブル内の更新する列を識別する UPDATE ステートメントを呼び出す 一意識別子は 一般には主キーフィールドの値で有る UPDATE ステートメントは 次の Transact-SQL ステートメントで示す様に 一意識別子 及び 更新する列と値の両方を含むパラメータを使用する UPDATE Customers SET CompanyName WHERE CustomerID 更新する列 値 一意識別子 メモ : パラメータのプレースホルダの構文は データソースに依って異なる 次に SQL Server のデータソースのプレースホルダの例を示す 猶 System.Data.OleDb パラメータや System.Data.Odbc パラメータでは プレースホルダと仕て 疑問符 (? ) を使用する 此の の例では CompanyName フィールドは CustomerID パラメータの値で更新される 此等のパラメータは SqlParameter オブジェクトの SourceColumn プロパティを使用して 変更された行から情報を取得する 前のサンプル UPDATE ステートメントのパラメータを次に示す 此のコードは 変数 adapter が有効な SqlDataAdapter オブジェクトを表す事を前提と仕て居る adapter.parameters.add("@companyname", SqlDbType.NChar, 15, "CompanyName") Dim parameter As SqlParameter = _ adapter.updatecommand.parameters.add("@customerid", _ SqlDbType.NChar, 5, "CustomerID") parameter.sourceversion = DataRowVersion.Original Parameters コレクションの Add メソッドは パラメータ名 DataAdapter 固有の型 サイズ ( 其の型に適用可能な場合 ) 及び DataTable の SourceColumn パラメータの SourceVersion が Original に設定されて居る事に注意され度い 此の設定に依り 変更済みの DataRow の中で 識別を行う 1 つ 又は 複数の列の値が既に変更されて居る場合に データソース内の既存の行を更新する事を保証出来る 識別列の値が既に変更されて居る場合は Original 行の値はデータソースの現在の値と一致し Current パラメータの SourceVersion は設定されて居ない為 既定の Current の行の値が使用される -21-
22 SqlClient の例 SQL ステートメントを SqlDataAdapter の SelectCommand InsertCommand UpdateCommand DeleteCommand の各プロパティの CommandText と仕て使用する例を次に示す SqlDataAdapter オブジェクトの場合は 名前付きのパラメータを使用する必要が有る Dim selectsql As String = _ "SELECT CustomerID, CompanyName FROM Customers " & _ "WHERE CountryRegion AND City Dim insertsql As String = _ "INSERT INTO Customers (CustomerID, CompanyName) " & _ "VALUES Dim updatesql As String = _ "UPDATE Customers SET CustomerID & _ "CompanyName " & _ "WHERE CustomerID Dim deletesql As String = _ "DELETE FROM Customers WHERE CustomerID string selectsql = "SELECT CustomerID, CompanyName FROM Customers WHERE CountryRegion = " + "@CountryRegion AND City string insertsql = "INSERT INTO Customers (CustomerID, CompanyName) " + "VALUES string updatesql = "UPDATE Customers SET CustomerID " + "CompanyName WHERE CustomerID string deletesql = "DELETE FROM Customers WHERE CustomerID OleDb 又は Odbc の例 OleDbDataAdapter オブジェクトと OdbcDataAdapter オブジェクトの場合は 疑問符 (? ) のプレースホルダを使用してパラメータを識別する必要が有る Dim selectsql As String = _ "SELECT CustomerID, CompanyName FROM Customers " & _ "WHERE CountryRegion =? AND City =?" Dim insertsql AS String = _ "INSERT INTO Customers (CustomerID, CompanyName) VALUES (?,?)" Dim updatesql AS String = _ "UPDATE Customers SET CustomerID =?, CompanyName =? WHERE CustomerID =?" Dim deletesql As String = "DELETE FROM Customers WHERE CustomerID =?" string selectsql = "SELECT CustomerID, CompanyName FROM Customers " + "WHERE CountryRegion =? AND City =?"; string insertsql = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (?,?)"; string updatesql = "UPDATE Customers SET CustomerID =?, CompanyName =? WHERE CustomerID =? "; string deletesql = "DELETE FROM Customers WHERE CustomerID =?"; -22-
23 パラメータと仕て使用されるクエリステートメントは 作成する必要の有る入力パラメータと出力パラメータを定義する パラメータを作成するには Parameters.Add メソッドか Parameter コンストラクタを使用して列名 データ型 及び サイズを指定する Integer 等組み込みのデータ型の場合は サイズを含める必要は無いし 其の場合は自動的に既定のサイズを指定する事に成る 前の例の SQL ステートメントのパラメータを作成し DataSet にデータを格納するコード例を次に示す SqlClient ' Assumes that connection is a valid SqlConnection object. Dim adapter As SqlDataAdapter = New SqlDataAdapter Dim selectcmd AS SqlCommand = New SqlCommand(selectSQL, connection) adapter.selectcommand = selectcmd ' Add parameters and set values. selectcmd.parameters.add("@countryregion", SqlDbType.NVarChar, 15).Value = "UK" selectcmd.parameters.add("@city", SqlDbType.NVarChar, 15).Value = "London" Dim customers As DataSet = New DataSet adapter.fill(customers, "Customers") // Assumes that connection is a valid SqlConnection object. SqlDataAdapter adapter = new SqlDataAdapter( ); SqlCommand selectcmd = new SqlCommand(selectSQL, connection); adapter.selectcommand = selectcmd; // Add parameters and set values. selectcmd.parameters.add("@countryregion", SqlDbType.NVarChar, 15).Value = "UK"; selectcmd.parameters.add("@city", SqlDbType.NVarChar, 15).Value = "London"; DataSet customers = new DataSet( ); adapter.fill(customers, "Customers"); OleDb ' Assumes that connection is a valid OleDbConnection object. Dim adapter As OleDbDataAdapter = New OleDbDataAdapter Dim selectcmd AS OleDbCommand = New OleDbCommand(selectSQL, connection) adapter.selectcommand = selectcmd ' Add parameters and set values. selectcmd.parameters.add("@countryregion", OleDbType.VarChar, 15).Value = "UK" selectcmd.parameters.add("@city", OleDbType.VarChar, 15).Value = "London" Dim customers As DataSet = New DataSet adapter.fill(customers, "Customers") // Assumes that connection is a valid OleDbConnection object. -23-
24 OleDbDataAdapter adapter = new OleDbDataAdapter( ); OleDbCommand selectcmd = new OleDbCommand(selectSQL, connection); adapter.selectcommand = selectcmd; // Add parameters and set values. selectcmd.parameters.add("@countryregion", OleDbType.VarChar, 15).Value = "UK"; selectcmd.parameters.add("@city", OleDbType.VarChar, 15).Value = "London"; DataSet customers = new DataSet( ); adapter.fill(customers, "Customers"); Odbc ' Assumes that connection is a valid OdbcConnection object. Dim adapter As OdbcDataAdapter = New OdbcDataAdapter Dim selectcmd AS OdbcCommand = New OdbcCommand(selectSQL, connection) adapter.selectcommand = selectcmd ' Add Parameters and set values. selectcmd.parameters.add("@countryregion", OdbcType.VarChar, 15).Value = "UK" selectcmd.parameters.add("@city", OdbcType.VarChar, 15).Value = "London" Dim customers As DataSet = New DataSet adapter.fill(customers, "Customers") // Assumes that connection is a valid OdbcConnection object. OdbcDataAdapter adapter = new OdbcDataAdapter( ); OdbcCommand selectcmd = new OdbcCommand(selectSQL, connection); adapter.selectcommand = selectcmd; //Add Parameters and set values. selectcmd.parameters.add("@countryregion", OdbcType.VarChar, 15).Value = "UK"; selectcmd.parameters.add("@city", OdbcType.VarChar, 15).Value = "London"; DataSet customers = new DataSet( ); adapter.fill(customers, "Customers"); メモ : 或るパラメータに対してパラメータ名がサポートされて居ない場合は Parameter1 から増分して行く既定名 ParameterN が割り当てられる パラメータ名を指定する時には ParameterN の名前付けルールを使用しない事を推奨する 此れは 指定した名前が ParameterCollection 内の既存のパラメータ名と競合しない様にする為で有る 指定した名前が既に存在する場合は 例外がスローされる Parameter.DbType パラメータの型は.NET Framework データプロバイダに固有の属性で有る型が指定されて居る場合は 其の値がデータソースに渡される前に Parameter の値.NET Framework データプロバイダ型に変換される Parameter オブジェクトの DbType プロパティを特定の DbType に設定する一般的な方法で Parameter の型を指定する事も出来る Parameter オブジェクトの.NET Framework データプロバイダ型は Parameter オブジェクトの Value -24-
25 の.NET Framework 型か 又は Parameter オブジェクトの DbType から推論される Parameter 値と仕て渡されるオブジェクト 又は 指定された DbType に基づいて推論される Parameter 型を 次の表に示す Framework System.Data.DbType SqlDbType OleDbType OdbcType OracleType bool Boolean Bit Boolean Bit Byte byte Byte TinyInt UnsignedTinyInt TinyInt Byte byte[] Binary VarBinary 1 VarBinary Binary Raw char 2 Char Char Byte DateTime DateTime DateTime DBTimeStamp DateTime DateTime Decimal Decimal Decimal Decimal Numeric Number double Double Float Double Double Double float Single Real Single Real Float Guid Guid UniqueIdentifier Guid UniqueIdentifier Raw Int16 Int16 SmallInt SmallInt SmallInt Int16 Int32 Int32 Int Int Int Int32 Int64 Int64 BitInt BigInt BigInt Number object Object Variant Variant 3 Blob string String NVarChar 4 VarWChar NVarChar NVarChar TimeSpan Time 5 DBTime Time DateTime UInt16 UInt16 6 UnsignedSmallInt Int UInt16 UInt32 UInt32 7 UnsignedInt BigInt UInt32 UInt64 UInt64 8 UnsignedBigInt Numeric Number AnsiString VarChar VarChar VarChar VarChar AnsiStringFixedLength Char Char Char Char Currency Money Currency 9 Number Date A DBDate Date DateTime SByte B TinyInt C SByte StringFixedLength NChar WChar NChar NChar Time D DBTime Time DateTime VarNumeric E VarNumeric F Number 1 バイト配列が VarBinary の最大サイズ (8000 バイト ) より大きい場合は 此の暗黙の変換はエラーに成る 8000 バイトを超えるバイト配列の場合は 明示的に SqlDbType を設定する 2 char からの SqlDbType の推論はサポートされて居ない 3 Object からの OdbcType の推論はサポートされて居ない 4 文字列が NVarChar の最大サイズ (4000 文字 ) より大きい場合 此の暗黙の変換はエラーに成る 4000 文字を超える文字列の場合は 明示的に SqlDbType を設定する 5 TimeSpan からの SqlDbType の推論はサポートされて居ない 6 UInt16 からの SqlDbType の推論はサポートされて居ない 7 UInt32 からの SqlDbType の推論はサポートされて居ない 8 UInt64 からの SqlDbType の推論はサポートされて居ない 9 Currency からの OdbcType の推論はサポートされて居ない A Date からの SqlType の推論はサポートされて居ない B SByte からの SqlType の推論はサポートされて居ない C SByte からの OdbcType の推論はサポートされて居ない D Time からの SqlType の推論はサポートされて居ない E VarNumeric からの SqlDbType の推論はサポートされて居ない F VarNumeric からの OdbcType の推論はサポートされて居ない メモ :.NET Framework Version 1.0 に同梱されて居る.NET Framework データプロバイダは Decimal パラメータ値の Precision と Scale を確認しない為 切り捨てられたデータがデータソースに挿入される事が有る.NET Framework Version 1.0 を使用して居る場合は Decimal 値の Precision と Scale を検証してからパラメータ値を設定する.NET Framework Version 1.1 以降では Decimal パラメータ値で無効な Precision が設定されて居る場合 例外がスローされる Decimal パラメータスケールを超える Scale 値は 切り捨てられる -25-
26 メモ :.NET Framework Version 1.0 以降では System.Data.SqlTypes を System.Data.SqlClient と共に使用する事が出来る 詳細に付いては SqlTypes の使用 を参照され度い Parameter.Direction Parameter の Direction を設定する為に ParameterDirection 列挙型で使用出来る値を次の表に示す メンバ名 説明 Input 此のパラメータは入力パラメータで有る ( 此れは 既定の設定で有る ) InputOutput 此のパラメータは入力と出力の両方の機能を持って居る Output 此のパラメータは出力パラメータで有る ReturnValue 此のパラメータは戻り値を表す Parameter の Direction を設定する方法を次のコード例に示す parameter.direction = ParameterDirection.Output Parameter.SourceColumn Parameter.SourceVersion SourceColumn 及び SourceVersion は Parameter コンストラクタに記述子と仕て渡したり 既存の Parameter のプロパティと仕て設定する事も出来る SourceColumn は Parameter の値の取得元で有る DataRow の DataColumn の名前で有る SourceVersion は DataAdapter が値を取得する為に使用する DataRow バージョンを指定する SourceVersion で使用出来る DataRowVersion 列挙型の値を次の表に示す メンバ名 説明 Current 此のパラメータは列の現在の値を使用する ( 此れは 既定の設定で有る ) Default 此のパラメータは列の DefaultValue を使用する Original 此のパラメータは列の元の値を使用する Proposed 此のパラメータは提示された値を使用する CustomerID 列を 2 CustomerID ) CustomerID の SourceColumn と仕て使用する UPDATE パラメータは CustomerID 列を DataRow の現在の値に更新する為に使用されて居る 其の為 SourceVersion を Current に設定した CustomerID SourceColumn パラメータは データソースの現在の行を識別する為に使用されて居る 其の行の Original バージョンで一致する列の値が見付かった為 SourceVersion を Original に設定した同じ SourceColumn(CustomerID) が使用されて居る SqlClient adapter.updatecommand.parameters.add( _ "@CustomerID", SqlDbType.NChar, 5, "CustomerID") adapter.updatecommand.parameters.add( _ "@CompanyName", SqlDbType.NVarChar, 40, "CompanyName") Dim parameter As SqlParameter = _ adapter.updatecommand.parameters.add("@oldcustomerid", _ SqlDbType.NChar, 5, "CustomerID") parameter.sourceversion = DataRowVersion.Original -26-
27 adapter.updatecommand.parameters.add( SqlDbType.NChar, 5, "CustomerID"); adapter.updatecommand.parameters.add( SqlDbType.NVarChar, 40, "CompanyName"); SqlParameter parameter = adapter.updatecommand.parameters.add( "@OldCustomerID", SqlDbType.NChar, 5, "CustomerID"); parameter.sourceversion = DataRowVersion.Original; UpdatedRowSource Command オブジェクトの UpdatedRowSource プロパティを使用すると データソースから返された値を DataSet に割り当てる方法を制御出来る UpdatedRowSource プロパティを UpdateRowSource 列挙型の値の 1 つに設定する事で DataAdapter コマンドが返したパラメータを無視するか DataSet 内の変更行に適用するかを制御出来る 最初に返された行 ( 存在する場合 ) を DataSet 内の変更行に適用するか何うかを指定する事も出来る UpdateRowSource 列挙型の様々の値と 其等の値が DataAdapter で使用されるコマンドの動作に何の様に影響するかを次の表で説明する UpdateRowSource 説明 Both 出力パラメータと返された結果セットの最初の行を DataSet 内の変更行に割り当てる FirstReturnedRecord 返された結果セットの最初の行のデータ丈を DataSet 内の変更行に割り当てる None 出力パラメータ又は返された結果セットの行が無視される OutputParameters 出力パラメータ丈を DataSet 内の変更行に割り当てる パラメータと戻り値の指定 ストアドプロシージャには 入力パラメータと出力パラメータの他に戻り値を含める事が出来る 次の例は ADO.NET が新しいレコードを 主キー列が SQL Server データベースの ID 列と成って居るテーブルに挿入して 入力パラメータ 出力パラメータ 及び 戻り値を受け渡す例を説明して居る 例 此の例では 次のストアドプロシージャを使用して Northwind Categories テーブルに新しいカテゴリを挿入する 此のストアドプロシージャは CategoryName 列の値を入力パラメータと仕て受け取り SCOPE_IDENTITY( ) 関数を使用して ID フィールド CategoryID の新しい値を取得し 其の値を出力パラメータ内に返す RETURN 関数を使用して 挿入された行の数を返す CREATE PROCEDURE int OUTPUT AS SET NOCOUNT ON INSERT INTO Categories (CategoryName) VALUES(@CategoryName) = SCOPE_IDENTITY( ) -27-
28 上述の InsertCategory ストアドプロシージャを SqlDataAdapter の InsertCommand 出力パラメータと戻り値は SqlDataAdapter の Update メソッドが呼び出され データベースにレコードが挿入された後で DataSet に反映される メモ : OleDbDataAdapter を使用する場合 ReturnValue の ParameterDirection を含むパラメータを他のパラメータより先に指定する必要が有る ' Assumes that connection represents a SqlConnection object. Dim adapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CategoryID, CategoryName FROM dbo.categories", connection) adapter.insertcommand = New SqlCommand("InsertCategory", connection) adapter.insertcommand.commandtype = CommandType.StoredProcedure Dim parameter As SqlParameter = adapter.insertcommand.parameters.add( _ "@RowCount", SqlDbType.Int) parameter.direction = ParameterDirection.ReturnValue adapter.insertcommand.parameters.add( _ "@CategoryName", SqlDbType.NChar, 15, "CategoryName") parameter = adapter.insertcommand.parameters.add( _ "@Identity", SqlDbType.Int, 0, "CategoryID") parameter.direction = ParameterDirection.Output Dim categoriesds As DataSet = New DataSet( ) adapter.fill(categoriesds, "Categories") Dim newrow As DataRow = categoriesds.tables("categories").newrow( ) newrow("categoryname") = "New Category" categoriesds.tables("categories").rows.add(newrow) adapter.update(categoriesds, "Categories") Dim rowcount As Int32 = CInt(adapter.InsertCommand.Parameters("@RowCount").Value) // Assumes that connection represents a SqlConnection object. SqlDataAdapter adapter = new SqlDataAdapter( "SELECT CategoryID, CategoryName FROM dbo.categories", connection); adapter.insertcommand = new SqlCommand("InsertCategory", connection); adapter.insertcommand.commandtype = CommandType.StoredProcedure; SqlParameter parameter = adapter.insertcommand.parameters.add( "@RowCount", SqlDbType.Int); parameter.direction = ParameterDirection.ReturnValue; adapter.insertcommand.parameters.add( "@CategoryName", SqlDbType.NChar, 15, "CategoryName"); parameter = adapter.insertcommand.parameters.add( -28-
29 SqlDbType.Int, 0, "CategoryID"); parameter.direction = ParameterDirection.Output; DataSet categoriesds = new DataSet( ); adapter.fill(categoriesds, "Categories"); DataRow newrow = categoriesds.tables["categories"].newrow( ); newrow["categoryname"] = "New Category"; categoriesds.tables["categories"].rows.add(newrow); adapter.update(categoriesds, "Categories"); Int32 rowcount = (Int32)adapter.InsertCommand.Parameters["@RowCount"].Value; DataSet の内容のマージ DataSet の Merge メソッドを使用して DataSet DataTable 又は DataRow の配列の内容を既存の DataSet にマージ出来る 一部の係数 及び オプションは 新しいデータを既存の DataSet にマージする方法に影響する 主キー マージに依って新しいデータとスキーマを受け取るテーブルに主キーが有る場合 受信データの新しい行の主キーと Original 行バージョンの主キーの値が同じで有る既存の行を一致させる 受信スキーマの列が既存のスキーマの列と一致する場合 既存の行に有るデータが変更される 既存のスキーマと一致しない列は MissingSchemaAction パラメータに基づいて無視 又は 追加される ( 此の資料の MissingSchemaAction を参照 ) 主キーの値が既存の行と一致しない新しい行は 既存のテーブルに追加される 受信する行 又は 既存する行の行状態が Added の場合 Original 行バージョンが存在しない為 Added の行の Current 行バージョンの主キーの値を使用して 其の 2 つの行の主キーの値を一致させる 受信テーブルと既存のテーブルに名前が同じでもデータ型が異なる列が含まれて居る場合 例外がスローされ DataSet の MergeFailed イベントが発生する 受信テーブルと既存のテーブルの両方にキーが定義されて居ても 主キーの対象の列が異なる場合 例外がスローされ DataSet の MergeFailed イベントが発生する マージに依って新しいデータを受け取るテーブルに主キーが無い場合 受信データの新しい行と其のテーブルの既存の行は一致しない 其の代わりに新しい行が既存のテーブルに追加される preservechanges DataSet DataTable 又は DataRow の各配列を Merge メソッドに渡すと オプションパラメータを含める事が出来る 其のパラメータを使用して 変更内容を既存の DataSet に保存するか何うか 及び 受信データで見付かった新しいスキーマの要素を処理する方法を指定する 受信データの後に続く最初のオプションパラメータは Boolean 型のフラグ preservechanges で 変更内容を既存の DataSet に保存するか何うかを指定する preservechanges フラグを true に設定した場合 既存する行の Current 行バージョンの値は受信する値で上書きされない preservechanges フラグを false に設定した場合 既存する行の Current 行バージョンの値は受信する値で上書きされる preservechanges フラグを指定しない場合 既定では false に設定される 行バージョンの詳細に付いては 行の状態とバージョン を参照され度い preservechanges を true にすると 既存する行のデータは Current 行バージョンで保存されるが 既 -29-
30 存する行の Original 行バージョンには受信する行の Original 行バージョンのデータで上書きされる 既存する行の RowState は Modified に設定される 適用する例外を次に示す 既存する行の RowState が Deleted の場合 此の RowState は Deleted の儘で Modified には設定されない 此の場合 受信する行のデータは既存する行の Original 行バージョンと仕て保存され 既存する行の Original 行バージョンのデータを上書きする ( 受信する行の RowState が Added でない場合 ) 受信する行の RowState が Added の場合 受信する行には Original 行バージョンが存在しない為 既存する行の Original 行バージョンのデータは上書きされない preservechanges を false にすると 既存する行の Current 行バージョンと Original 行バージョンの孰れのデータも受信する行のデータで上書きされ 既存する行の RowState には受信する行の RowState が設定される 適用する例外を次に示す 受信する行の RowState が Unchanged で 既存する行の RowState が Modified Deleted 又は Added の場合 既存する行の RowState は Modified に設定される 受信する行の RowState が Added で 既存する行の RowState が Unchanged Modified 又は Deleted の場合 既存する行の RowState は Modified に設定される 亦 受信する行には Original 行バージョンが存在しない為 既存する行の Original 行バージョンのデータは 受信する行のデータで上書きされない MissingSchemaAction Merge メソッドのオプションの MissingSchemaAction パラメータを使用して 既存の DataSet の一部ではない受信データのスキーマ要素を Merge で処理する方法を指定出来る MissingSchemaAction のオプションの説明を次の表に示す MissingSchemaAction のオプション Add AddWithKey Error Ignore 説明新しいスキーマ情報を DataSet に追加し 受信する値を新しい列に読み込む ( 此れは 既定の設定で有る ) 新しいスキーマと主キーの情報を DataSet に追加し 受信する値を新しい列に読み込む 一致しないスキーマ情報が見付かった場合 例外をスローする 新しいスキーマ情報を無視する 制約 Merge メソッドを使用すると 総ての新しいデータが既存の DataSet に追加される迄 制約がチェックされない 新しいデータを追加すると DataSet の現在の値に制約が適用される 開発者は 制約違反の為にスローされる例外をコードで処理する必要が有る 例えば DataSet に既存する行が Unchanged で 主キーの値が 1 の場合に 受信する行が Modified で Original 行バージョンの主キーの値が 2 Current 行バージョンの主キーの値が 1 の状態でマージ操作を行うと Original の主キーの値が異なる為 既存する行と受信する行は一致と看做されない マージが完了し 制約がチェックされると Current 行バージョンの主キーの値が主キー列の UNIQUE 制約に違反する為 例外がスローされる スキーマが異なる 2 つの DataSet オブジェクトを 其の 2 つの受信 DataSet オブジェクトのスキーマを組み合わせて 1 つの DataSet にマージするコード例を次に示す -30-
31 Using connection As SqlConnection = New SqlConnection( connectionstring) Dim adapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CustomerID, CompanyName FROM Customers", connection) connection.open( ) Dim customers As DataSet = New DataSet( ) adapter.fillschema(customers, SchemaType.Source, "Customers") adapter.fill(customers, "Customers") Dim orders As DataSet = New DataSet( ) orders.readxml("orders.xml", XmlReadMode.ReadSchema) orders.acceptchanges( ) customers.merge(orders, True, MissingSchemaAction.AddWithKey) End Using using (SqlConnection connection = new SqlConnection(connectionString)) SqlDataAdapter adapter = new SqlDataAdapter( "SELECT CustomerID, CompanyName FROM dbo.customers", connection); connection.open( ); DataSet customers = new DataSet( ); adapter.fillschema(customers, SchemaType.Source, "Customers"); adapter.fill(customers, "Customers"); DataSet orders = new DataSet( ); orders.readxml("orders.xml", XmlReadMode.ReadSchema); orders.acceptchanges( ); customers.merge(orders, true, MissingSchemaAction.AddWithKey); 更新内容を含む既存の DataSet を取得し 其の更新内容を DataAdapter に渡してデータソースで処理するコード例を次に示す 其の後 其の結果が元の DataSet にマージされる エラーと成った変更内容を拒否した後 マージされた変更内容が AcceptChanges を使用してコミットされる Dim customers As DataTable = dataset.tables("customers") ' Make modifications to the Customers table. ' Get changes to the DataSet. Dim datasetchanges As DataSet = dataset.getchanges( ) ' Add an event handler to handle the errors during Update. AddHandler adapter.rowupdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated) connection.open( ) adapter.update(datasetchanges, "Customers") connection.close( ) ' Merge the updates. dataset.merge(datasetchanges, True, MissingSchemaAction.Add) -31-
32 ' Reject changes on rows with errors and clear the error. Dim errrows( ) As DataRow = dataset.tables("customers").geterrors( ) Dim errrow As DataRow For Each errrow In errrows errrow.rejectchanges( ) errrow.rowerror = Nothing Next ' Commit the changes. dataset.acceptchanges( ) DataTable customers = dataset.tables["customers"]; // Make modifications to the Customers table. // Get changes to the DataSet. DataSet datasetchanges = dataset.getchanges( ); // Add an event handler to handle the errors during Update. adapter.rowupdated += new SqlRowUpdatedEventHandler(OnRowUpdated); connection.open( ); adapter.update(datasetchanges, "Customers"); connection.close( ); // Merge the updates. dataset.merge(datasetchanges, true, MissingSchemaAction.Add); // Reject changes on rows with errors and clear the error. DataRow[] errrows = dataset.tables["customers"].geterrors( ); foreach (DataRow errrow in errrows) errrow.rejectchanges( ); errrow.rowerror = null; // Commit the changes. dataset.acceptchanges( ); Private Sub OnRowUpdated(ByVal sender As Object, ByVal args As SqlRowUpdatedEventArgs) If args.status = UpdateStatus.ErrorsOccurred Then args.row.rowerror = args.errors.message args.status = UpdateStatus.SkipCurrentRow End If End Sub protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args) if (args.status == UpdateStatus.ErrorsOccurred) args.row.rowerror = args.errors.message; args.status = UpdateStatus.SkipCurrentRow; -32-
33 DataSet の内容のコピー DataSet のコピーを作成すると 元のデータに影響せずにデータを使用したり DataSet のデータのサブセットを使用したり出来る DataSet をコピーすると 次の操作を行う事が出来る スキーマ データ 行状態情報 行バージョン等の DataSet の正確なコピーを作成出来る 既存の DataSet のスキーマを含み 行丈を変更した DataSet を作成出来る 変更された総ての行を返したり 特定の DataRowState を指定したり出来る 行の状態の詳細に付いては 行の状態とバージョン を参照され度い 行をコピーせずに DataSet のスキーマ ( リレーショナル構造 ) 丈をコピー出来る ImportRow を使用して 行を既存の DataTable にインポート出来る スキーマとデータを含む DataSet の正確なコピーを作成するには DataSet の Copy メソッドを使用する DataSet の正確なコピーを作成する方法を次のコード例に示す Dim copydataset As DataSet = customerdataset.copy( ) DataSet copydataset = customerdataset.copy( ); スキーマ 及び データが Added Modified 又は Deleted で或る行丈を含む DataSet のコピーを作成するには DataSet の GetChanges メソッドを使用する 亦 GetChanges の呼出時に DataRowState の値を渡す事に依って GetChanges を使用して特定の行状態の行丈を返す事が出来る GetChanges の呼出時に DataRowState を渡す方法を次のコード例に示す ' Copy all changes. Dim changedataset As DataSet = customerdataset.getchanges( ) ' Copy only new rows. Dim addeddatasetas DataSet = customerdataset.getchanges(datarowstate.added) // Copy all changes. DataSet changedataset = customerdataset.getchanges( ); // Copy only new rows. DataSet addeddataset= customerdataset.getchanges(datarowstate.added); スキーマ丈を含む DataSet のコピーを作成するには DataSet の Clone メソッドを使用する 亦 DataTable の ImportRow メソッドを使用して 複製した DataSet に既存の行を追加する事も出来る ImportRow メソッドを使用すると データ 行の状態 及び 行バージョンの情報が指定したテーブルに追加される 列名が一致し データ型が互換性の有る型の場合には 列の値丈が追加される DataSet のクローンを作成し CountryRegion 列の値が Germany の顧客に対する DataSet のクローン内の Customers テーブルに 元の DataSet の行を追加するコード例を次に示す Dim germanycustomers As DataSet = customerdataset.clone( ) Dim copyrows( ) As DataRow = _ customerdataset.tables("customers").select("countryregion = 'Germany'") -33-
34 Dim customertable As DataTable = germanycustomers.tables("customers") Dim copyrow As DataRow For Each copyrow In copyrows customertable.importrow(copyrow) Next DataSet germanycustomers = customerdataset.clone( ); DataRow[] copyrows = customerdataset.tables["customers"].select("countryregion = 'Germany'"); DataTable customertable = germanycustomers.tables["customers"]; foreach (DataRow copyrow in copyrows) customertable.importrow(copyrow); DataSet イベントの使用 DataSet には DataSet オブジェクトのスキーマのマージで競合が発生すると 生成される MergeFailed イベントが設定されて居る 例えば マージ対象のテーブルの主キーの列が 2 つの DataSet オブジェクトのテーブル間で異なる場合 例外がスローされ MergeFailed イベントが発生する MergeFailed イベントに渡される MergeFailedEventArgs には 2 つの DataSet オブジェクト間のスキーマで発生した競合を示す Conflict プロパティ 及び 競合が発生したテーブルの名前を示す Table プロパティが有る DataSet の使用時に使用出来る其の他のイベントに付いては DataTable イベントの使用 及び DataAdapter イベントの使用 を参照され度い MergeFailed イベントをイベントハンドラに追加するコード例を次に示す Dim workds As DataSet = New DataSet AddHandler workds.mergefailed, New MergeFailedEventHandler(AddressOf DataSetMergeFailed) Private Shared Sub DataSetMergeFailed(sender As Object,args As MergeFailedEventArgs) Console.WriteLine("Merge failed for table " & args.table.tablename) Console.WriteLine("Conflict = " & args.conflict) End Sub DataSet workds = new DataSet( ); workds.mergefailed += new MergeFailedEventHandler(DataSetMergeFailed); private static void DataSetMergeFailed(object sender, MergeFailedEventArgs args) Console.WriteLine("Merge failed for table " + args.table.tablename); Console.WriteLine("Conflict = " + args.conflict); 型指定された DataSet の使用 厳密に型指定されて居ない変数を使用した値への遅延バインディングアクセスに加えて DataSet には 厳密に型指定された変数を使用したデータへのアクセスも用意されて居る DataSet の一部で有るテーブルと列は ユーザーが認識しやすい名前と厳密に型指定された変数を使用してアクセス出来る -34-
35 型指定された DataSet とは DataSet から派生するクラスの事で有る 従って 型指定された DataSet は DataSet の総てのメソッド イベント 及び プロパティを継承する 更に 型指定された DataSet には 厳密に型指定されたメソッド イベント 及び プロパティが用意されて居る 詰まり コレクションベースのメソッドを使用せずに名前でテーブルや列にアクセス出来る コードが読み易く変更された丈でなく 型指定された DataSet を使用して 入力する通りにラインを Visual Studio.NET コードエディタに自動挿入出来る 更に 厳密に型指定された DataSet を使用してコンパイル時に正しい型で値にアクセス出来る 厳密に型指定された DataSet を使用すると 型の不一致が実行時ではなく コードのコンパイル時にキャッチされる 厳密に型指定された DataSet の生成 XML スキーマ定義言語 (XSD) 標準に準拠する XML スキーマを設定すると.NET Framework SDK と共に用意される XSD.exe ツールを使用して 厳密に型指定された DataSet を生成出来る XSD.exe ツールを使用して DataSet を生成する構文を次のコードで示す xsd.exe /d /l:cs XSDSchemaFileName.xsd /n:xsdschema.namespace 此の構文では /d ディレクティブが DataSet を生成する事を知らせる 亦 /l: ディレクティブは使用する言語 (.NET 等 ) をツールに知らせる オプションの /n: ディレクティブは XSDSchema.Namespace と呼ばれる DataSet の名前空間も生成する事をツールに知らせる コマンドの出力は XSDSchemaFileName.cs で ADO.NET アプリケーションでコンパイルと使用が出来る 生成されたコードをライブラリ 又は モジュールと仕てコンパイル出来る コンパイラ (csc.exe) を使用して 生成されたコードをライブラリと仕てコンパイルする構文を次のコードで示す csc.exe /t:library XSDSchemaFileName.cs /r:system.dll /r:system.data.dll /t: ディレクティブはライブラリと仕てコンパイルする事をツールに知らせ /r: ディレクティブはコンパイルに必要な依存ライブラリを指定する コマンドの出力は XSDSchemaFileName.dll で /r: ディレクティブに依る ADO.NET アプリケーションのコンパイル時にコンパイラに渡す事が出来る ADO.NET アプリケーションの XSD.exe に渡された名前空間にアクセスする構文を次のコードで示す Imports XSDSchema.Namespace using XSDSchema.Namespace; CustomerDataSet と謂う名前の型指定された DataSet を使用して Northwind データベースから顧客リストを読み込むコード例を次に示す Fill メソッドを使用してデータが読み込まれると 例では 型指定された CustomersRow(DataRow) オブジェクトを使用して Customers テーブルの各顧客をループする 此れに依り DataColumnCollection を経由せずに CustomerID 列に直接アクセス出来る Dim customers As CustomerDataSet= New CustomerDataSet( ) Dim adapter As SqlDataAdapter New SqlDataAdapter( _ "SELECT * FROM dbo.customers;", _ "Data Source=(local);Integrated " & _ -35-
36 "Security=SSPI;Initial Catalog=Northwind") adapter.fill(customers, "Customers") Dim customerrow As CustomerDataSet.CustomersRow For Each customerrow In customers.customers Console.WriteLine(customerRow.CustomerID) Next CustomerDataSet customers = new CustomerDataSet( ); SqlDataAdapter adapter = new SqlDataAdapter( "SELECT * FROM dbo.customers;", "Data Source=(local);Integrated " + "Security=SSPI;Initial Catalog=Northwind"); adapter.fill(customers, "Customers"); foreach(customerdataset.customersrow customerrow in customers.customers) Console.WriteLine(customerRow.CustomerID); 例に使用された XML スキーマを次に示す <?xml version="1.0" encoding="utf-8"?> <xs:schema id="customerdataset" xmlns="" xmlns:xs=" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="customerdataset" msdata:isdataset="true"> <xs:complextype> <xs:choice maxoccurs="unbounded"> <xs:element name="customers"> <xs:complextype> <xs:sequence> <xs:element name="customerid" type="xs:string" minoccurs="0" /> </xs:sequence> </xs:complextype> </xs:element> </xs:choice> </xs:complextype> </xs:element> </xs:schema> 型指定された DataSet に依る注釈の使用 注釈を使用すると 基に成るスキーマを変更せずに型指定された DataSet の要素の名前を変更出来る 基に成るスキーマの要素の名前を変更すると データソースに有るオブジェクトへの参照が失われる丈でなく 型指定された DataSet がデータソースに無いオブジェクトを参照する事に成る 注釈を使用すると 基に成るスキーマを変更せずに 型指定された DataSet のオブジェクトを解り易い名前にカスタマイズ出来る為 コードが読み易く成り 型指定された DataSet がクライアントで使用し易く成る 例えば 次の Northwind データベースの Customers テーブルのスキーマ要素は CustomersRow と謂う名前の DataRow オブジェクト名 及び Customers と謂う名前の DataRowCollection と成る <xs:element name="customers"> <xs:complextype> -36-
37 <xs:sequence> <xs:element name="customerid" type="xs:string" minoccurs="0" /> </xs:sequence> </xs:complextype> </xs:element> Customers と謂う DataRowCollection 名は クライアントコードでは意味が有るが CustomersRow と謂う DataRow 名は単一のオブジェクトで有る為 誤解が生じる 亦 一般的なシナリオでは CustomersRow オブジェクトは Row ID を指定せずに参照される為 単に Customer オブジェクトと仕て参照される 此の問題を解決するには スキーマに注釈を付け DataRow オブジェクトと DataRowCollection オブジェクトに新しい名前を指定する 上記のスキーマに注釈を付けたスキーマを次に示す <xs:element name="customers" codegen:typedname="customer" codegen:typedplural="customers"> <xs:complextype> <xs:sequence> <xs:element name="customerid" type="xs:string" minoccurs="0" /> </xs:sequence> </xs:complextype> </xs:element> Customer と謂う typedname 値を指定すると Customer と謂う DataRow オブジェクト名に成る Customers と謂う typedplural 値を指定すると Customers と謂う DataRowCollection 名が保存される 使用出来る注釈を次の表に示す 注釈 説明 typedname オブジェクト名 typedplural オブジェクトのコレクション名 typedparent 親のリレーションシップで参照される場合のオブジェクト名 typedchildren 子のリレーションシップからオブジェクトを返すメソッド名 nullvalue 基に成る値が DBNull の場合の値 (nullvalue の注釈に付いては 次の表を参照され 度い 既定値は _throw で有る ) nullvalue 注釈に指定出来る値を次の表に示す nullvalue の値 説明 Replacement Value 返される値を指定する ( 返された値は要素の型と一致する必要が有る 例えば 整数型フィールドが null の場合に 0 を返す為に nullvalue="0" を使用する ) _throw 例外をスローする ( 此れは 既定の設定で有る ) _null プリミティブ型が見付かった場合は null 参照を返すか 例外をスローする _empty 文字列の場合は String.Empty を 其れ以外の場合は空のコンストラクタから 作成されたオブジェクトを返す ( プリミティブ型が見付かった場合 例外をス ローする ) 型指定された DataSet のオブジェクトの既定値と使用出来る注釈を次の表に示す オブジェクト / メソッド / イベント 既定値 注釈 DataTable TableNameDataTable typedplural DataTable のメソッド NewTableNameRow AddTableNameRow DeleteTableNameRow typedname -37-
38 DataRowCollection TableName typedplural DataRow TableNameRow typedname DataColumn DataTable.ColumnNameColumn typedname DataRow.ColumnName Property PropertyName typedname Child Accessor GetChildTableNameRows typedchildren Parent Accessor TableNameRow typedparent DataSet イベント TableNameRowChangeEvent TableNameRowChangeEventHandler typedname 型指定された DataSet の注釈を使用するには XML スキーマ定義言語 (XSD) スキーマに次の xmlns 参照をインクルードする必要が有る xmlns:codegen="urn:schemas-microsoft-com:xml-msprop" Orders テーブルとのリレーションを持つ Northwind データベースの Customers テーブルを表示する注釈の付いたスキーマのサンプルを次に示す <?xml version="1.0" encoding="utf-8"?> <xs:schema id="customerdataset" xmlns:codegen="urn:schemas-microsoft-com:xml-msprop" xmlns="" xmlns:xs=" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="customerdataset" msdata:isdataset="true"> <xs:complextype> <xs:choice maxoccurs="unbounded"> <xs:element name="customers" codegen:typedname="customer" codegen:typedplural="customers"> <xs:complextype> <xs:sequence> <xs:element name="customerid" codegen:typedname="customerid" type="xs:string" minoccurs="0" /> <xs:element name="companyname" codegen:typedname="companyname" type="xs:string" minoccurs="0" /> <xs:element name="phone" codegen:typedname="phone" codegen:nullvalue="" type="xs:string" minoccurs="0" /> </xs:sequence> </xs:complextype> </xs:element> <xs:element name="orders" codegen:typedname="order" codegen:typedplural="orders"> <xs:complextype> <xs:sequence> <xs:element name="orderid" codegen:typedname="orderid" type="xs:int" minoccurs="0" /> <xs:element name="customerid" codegen:typedname="customerid" codegen:nullvalue="" type="xs:string" minoccurs="0" /> <xs:element name="employeeid" codegen:typedname="employeeid" codegen:nullvalue="0" type="xs:int" minoccurs="0" /> <xs:element name="orderadapter" codegen:typedname="orderadapter" codegen:nullvalue=" t00:00:00" type="xs:datetime" minoccurs="0" /> </xs:sequence> </xs:complextype> </xs:element> </xs:choice> </xs:complextype> <xs:unique name="constraint1"> <xs:selector xpath=".//customers" /> <xs:field xpath="customerid" /> </xs:unique> <xs:keyref name="custorders" refer="constraint1" codegen:typedparent="customer" codegen:typedchildren="getorders"> <xs:selector xpath=".//orders" /> <xs:field xpath="customerid" /> </xs:keyref> </xs:element> </xs:schema> -38-
39 サンプルスキーマから作成された厳密に型指定された DataSet を次のコード例で使用する 亦 一方の SqlDataAdapter を使用して Customers テーブルを 他方の SqlDataAdapter を使用して Orders テーブルを作成する 厳密に型指定された DataSet に依り DataRelations が定義される ' Assumes a valid SqlConnection object named connection. Dim customeradapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CustomerID, CompanyName, Phone FROM Customers", connection) Dim orderadapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT OrderID, CustomerID, EmployeeID, OrderAdapter FROM Orders", connection) ' Populate a strongly typed DataSet. connection.open( ) Dim customers As CustomerDataSet = New CustomerDataSet( ) customeradapter.fill(customers, "Customers") orderadapter.fill(customers, "Orders") connection.close( ) ' Add a strongly typed event. AddHandler customers.customers.customerchanged, & New CustomerDataSet.CustomerChangeEventHandler( AddressOf OnCustomerChanged) ' Add a strongly typed DataRow. Dim newcustomer As CustomerDataSet.Customer = customers.customers.newcustomeromer( ) newcustomer.customerid = "NEW01" newcustomer.companyname = "My New Company" customers.customers.addcustomer(newcustomer) ' Navigate the child relation. Dim customer As CustomerDataSet.Customer Dim order As CustomerDataSet.Order For Each customer In customers.customers Console.WriteLine(customer.CustomerID) For Each order In customer.getorders( ) Console.WriteLine(vbTab & order.orderid) Next Next Private Shared Sub OnCustomerChanged( _ sender As Object, e As CustomerDataSet.CustomerChangeEvent) End Sub // Assumes a valid SqlConnection object named connection. SqlDataAdapter customeradapter = new SqlDataAdapter( "SELECT CustomerID, CompanyName, Phone FROM Customers", connection); SqlDataAdapter orderadapter = new SqlDataAdapter( "SELECT OrderID, CustomerID, EmployeeID, OrderAdapter FROM Orders", connection); // Populate a strongly typed DataSet. connection.open( ); CustomerDataSet customers = new CustomerDataSet( ); customeradapter.fill(customers, "Customers"); orderadapter.fill(customers, "Orders"); -39-
40 connection.close( ); // Add a strongly typed event. customers.customers.customerchanged += new CustomerDataSet.CustomerChangeEventHandler(OnCustomerChanged); // Add a strongly typed DataRow. CustomerDataSet.Customer newcustomer = customers.customers.newcustomeromer( ); newcustomer.customerid = "NEW01"; newcustomer.companyname = "My New Company"; customers.customers.addcustomer(newcustomer); // Navigate the child relation. foreach(customerdataset.customer customer in customers.customers) Console.WriteLine(customer.CustomerID); foreach(customerdataset.order order in customer.getorders( )) Console.WriteLine(" t" + order.orderid); protected static void OnCustomerChanged( object sender, CustomerDataSet.CustomerChangeEvent e) DataTable の作成と使用 DataSet は テーブル リレーションシップ 及び 制約のコレクションで構成される ADO.NET では DataSet 内のテーブルを表す為に DataTable オブジェクトを使用する DataTable は 1 つのメモリ内のリレーショナルデータテーブルを表す 此のテーブルのデータは 其のデータが存在する.NET ベースアプリケーションのローカルデータだが DataAdapter を使用して Microsoft SQL Server 等のデータソースから読み込む事も出来る 詳細に付いては DataAdapter からの DataSet の読み込み を参照され度い DataTable クラスは.NET Framework クラスライブラリ内の System.Data 名前空間のメンバで有る DataTable は 単独でも DataSet のメンバと仕ても作成 使用出来る 亦 DataTable オブジェクトは DataView 等の他の.NET Framework オブジェクトからも使用出来る DataSet 内のテーブルのコレクションには DataSet オブジェクトの Tables プロパティを使用してアクセスする テーブルのスキーマ ( 構造 ) は 列と制約で表される DataTable のスキーマは DataColumn ForeignKeyConstraint UniqueConstraint の各オブジェクトを使用して定義する テーブル内の列は データソースの列に割り当てたり 式で算出された値を格納したり 格納されて居る値を自動的にインクリメントしたり 主キー値を格納したり出来る DataTable には スキーマ丈でなく データを格納して順序付ける為の行も必要で有る DataRowDataRow クラスは テーブルに格納される実際のデータを表す DataRow や其のプロパティとメソッドを使用して テーブル内のデータを取得 評価 及び 操作出来る 行内のデータがアクセスされて変更された時は DataRow オブジェクトは 変更後の現在の状態と変更前の状態を維持する テーブル間で 1 つ以上の列を関連付け テーブル間の親子のリレーションシップを作成出来る DataTable オブジェクト間のリレーションシップを作成するには DataRelation を使用する -40-
41 DataRelation オブジェクトを使用すると 特定の行に関連付けられた子の行 又は 親の行を返す事が出来る 詳細に付いては テーブル間のリレーションシップの追加 を参照され度い DataTable の作成 DataTable は 1 つのインメモリリレーショナルデータのテーブルを表す DataTable は単独で作成 使用する事も 他の.NET Framework オブジェクトから DataSet のメンバと仕て使用する事も出来る DataTable オブジェクトは 適切な DataTable コンストラクタを使用する事に依り作成出来る 此のオブジェクトを DataSet に追加するには Add メソッドを使用して DataTable オブジェクトの Tables コレクションにオブジェクトを追加する DataSet の内部で DataTable オブジェクトを作成する場合は DataAdapter オブジェクトの Fill メソッド 又は FillSchema メソッドを使用出来る 亦 定義済みや推論に依る XML スキーマで DataSet の ReadXml ReadXmlSchema 又は InferXmlSchema の各メソッドを使用して作成する事も出来る DataTable を 1 つの DataSet の Tables コレクションのメンバと仕て追加した後で 其の DataTable を他の DataSet のテーブルのコレクションに追加する事は出来ない 最初に作成した時点では DataTable にはスキーマ ( 構造 ) が無い テーブルのスキーマを定義するには DataColumn オブジェクトを作成し テーブルの Columns コレクションに追加する必要が有る テーブルの主キー列を定義したり Constraint オブジェクトを作成してテーブルの Constraints コレクションに追加したりする事も出来る DataTable のスキーマを定義した後で DataRow オブジェクトをテーブルの Rows コレクションに追加する事に依り データ行をテーブルに追加出来る DataTable を作成する時に TableName プロパティの値を指定する必要は無い 此のプロパティは 後から指定する事も 空の儘に仕て置く事も出来る 但し TableName 値の無いテーブルを DataSet に追加した場合 其のテーブルの名前は既定のテーブル名 TableN に成る 此の既定名は Table0 に相当する Table から始まり 連続する番号が割り当てられて行く メモ :TableName 値を指定する時には TableN の命名規則を使用しない事を推奨する 此れは 指定した名前が DataSet に既に存在する既定のテーブル名と競合しない様にする為で有る 指定した名前が既に存在する場合は 例外がスローされる DataTable オブジェクトのインスタンスを作成し Customers と謂う名前を割り当てる例を次に示す Dim worktable as DataTable = New DataTable("Customers") DataTable worktable = new DataTable("Customers"); DataTable のインスタンスを作成し DataSet の Tables コレクションに追加する例を次に示す Dim customers As DataSet = New DataSet Dim customerstable As DataTable = customers.tables.add("customerstable") DataSet customers = new DataSet( ); DataTable customerstable = customers.tables.add("customerstable"); DataTable のスキーマの定義 テーブルのスキーマ ( 構造 ) は 列と制約で表される DataTable のスキーマは DataColumn -41-
42 ForeignKeyConstraint UniqueConstraint の各オブジェクトを使用して定義する テーブルの列は データソースの列に割り当てたり 式で算出された値を格納したり 格納されて居る値を自動的にインクリメントしたり 主キー値を格納したり出来る テーブルの列 リレーション 及び 制約を名前で参照する場合は 大文字と小文字が区別される 複数の列 リレーション 又は 制約の名前が同じで有っても 大文字と小文字が異なって居れば 1 つのテーブルで使用出来る 例えば Col1 と col1 を同時に使用出来る 此の場合 列を名前で参照する時は 列名の大文字と小文字を正確に指定する必要が有る 正確に指定しない場合は 例外がスローされる 例えば テーブル mytable に列 Col1 と列 col1 が有る場合 Col1 は名前 mytable.columns["col1"] で参照され col1 は名前 mytable.columns["col1"] で参照される 孰れかの列を mytable.columns["col1"] と謂う名前で参照しようとすると 例外が生成される 大文字と小文字の区別の規則は 特定の名前の列 リレーション 又は 制約が 1 つしかない場合には適用されない 詰まり 特定の列 リレーション 又は 制約オブジェクトと名前が一致する列 リレーション 又は 制約オブジェクトがテーブルに存在しない場合は 大文字と小文字を区別せずに其のオブジェクトを名前で参照する事が出来る 此の時 例外はスローされない 例えば テーブルに Col1 が 1 つしかない場合は my.columns["col1"] を使用して此の列を参照出来る メモ : 従って 此の動作は DataTable の CaseSensitive プロパティの影響を受けない CaseSensitive プロパティは テーブルのデータに適用され 並替 検索 フィルタ処理 制約の適用等に影響を及ぼす 此のプロパティは テーブルの列 リレーション 及び 制約の参照には適用されない テーブルへの列の追加 DataTable には テーブルの Columns プロパティに依って参照される DataColumn オブジェクトのコレクションが格納される 此の列のコレクションと制約に依って テーブルのスキーマ ( 構造 ) が定義される テーブル内で DataColumn オブジェクトを作成するには DataColumn コンストラクタを使用するか 又は DataColumnCollection の 1 つで有る テーブルの Columns プロパティの Add メソッドを呼び出す Add メソッドは オプションの ColumnName DataType Expression の各引数を受け取り 新しい DataColumn をコレクションのメンバと仕て作成する 亦 此のメソッドは既存の DataColumn オブジェクトを受け取り 此のオブジェクトをコレクションに追加する 必要な場合には 追加された DataColumn への参照を返す DataTable オブジェクトはデータソースに依存しない為 DataColumn のデータ型を指定する時には.NET Framework 型が使用される DataTable に 4 つの列を追加する例を次に示す Dim worktable As DataTable = New DataTable("Customers") Dim workcol As DataColumn = worktable.columns.add("custid", Type.GetType("System.Int32")) workcolumn.allowdbnull = false workcolumn.unique = true worktable.columns.add("custlname", Type.GetType("System.String")) worktable.columns.add("custfname", Type.GetType("System.String")) worktable.columns.add("purchases", Type.GetType("System.Double")) DataTable worktable = new DataTable("Customers"); DataColumn workcol = worktable.columns.add("custid", typeof(int32)); workcol.allowdbnull = false; workcol.unique = true; worktable.columns.add("custlname", typeof(string)); worktable.columns.add("custfname", typeof(string)); worktable.columns.add("purchases", typeof(double)); -42-
43 此の例では DBNull 値を許可せずに値を一意の値に制約する様に CustID 列のプロパティが設定されて居る 但し CustID 列をテーブルの主キー列と仕て定義した場合 AllowDBNull プロパティは自動的に false に設定され Unique プロパティは自動的に true に設定される 詳細に付いては テーブルの主キーの定義 を参照され度い 注意 : 列名が指定されて居ない列を DataColumnCollection に追加する場合 此の列には Column1 から始まるインクリメンタル既定名 ColumnN が割り当てられる 列名を指定する時には ColumnN の命名規則を使用しない事を推奨する 此れは 指定した名前が DataColumnCollection に既に存在する既定の列名と競合しない様にする為で有る 指定した名前が既に存在する場合は 例外がスローされる 式列の作成 列の式を定義すると 同じ行の他の列値 又は テーブル内の複数の行の列値に基づいて計算した値を 其の列に格納出来る 評価する式を定義するには 対象の列の Expression プロパティを使用し 其の式で ColumnName プロパティを使用して他の列を参照する 式列の DataType は 其の式が返す値に適した型で有る事が必要で有る テーブル内の式列で使用出来る幾つかの式の種類を次の表に示す 式の種類 比較 "Total >= 500" 計算 "UnitPrice * Quantity" 集約 Sum(Price) 例 次の例に示す様に 既存の DataColumn オブジェクトの Expression プロパティを設定したり 此のプロパティを DataColumn コンストラクタに渡す 3 番目の引数と仕て使用したり出来る worktable.columns.add("total",type.gettype("system.double")) worktable.columns.add("salestax", Type.GetType("System.Double"), "Total * 0.086") worktable.columns.add("total", typeof(double)); worktable.columns.add("salestax", typeof(double), "Total * 0.086"); 式は他の式列を参照出来る 但し 2 つの式が相互に参照し合う循環参照の場合は 例外が生成される 式の記述の規則に付いては DataColumn クラスの Expression プロパティの資料を参照され度い AutoIncrement 列の作成 列値を一意にする為に 新しい行がテーブルに追加された時に列値が自動的にインクリメントされる様に設定出来る 自動インクリメント DataColumn を作成するには 列の AutoIncrement プロパティを true に設定する DataColumn の値は AutoIncrementSeed プロパティで定義された値から開始され 行が追加される度に AutoIncrement 列の値には 列の AutoIncrementStep プロパティで定義された値が加算される AutoIncrement 列では DataColumn の ReadOnly プロパティを true に設定する事を推奨する 値 200 から開始して 3 宛インクリメントする列を作成する方法を次の例に示す Dim workcolumn As DataColumn = worktable.columns.add("customerid", typeof(int32)) workcolumn.autoincrement = true -43-
44 workcolumn.autoincrementseed = 200 workcolumn.autoincrementstep = 3 DataColumn workcolumn = worktable.columns.add("customerid", typeof(int32)); workcolumn.autoincrement = true; workcolumn.autoincrementseed = 200; workcolumn.autoincrementstep = 3; テーブルの主キーの定義 通常 データベーステーブルには テーブル内の各行を一意に識別する単一の列 又は 複数の列が有る 行を識別する此の様な列を 主キーと呼ぶ 1 つの DataColumn を DataTable の PrimaryKey と仕て指定すると テーブルは其の列の AllowDBNull プロパティを false に Unique プロパティを true に自動的に設定する 複数列の主キーの場合は AllowDBNull プロパティ丈が自動的に false に設定される DataTable の PrimaryKey プロパティが其の値と仕て 1 つ以上の DataColumn オブジェクトから成る配列を受け取る例を次に示す 最初の例は 1 つの列を主キーと仕て定義して居る worktable.primarykey = New DataColumn( ) worktable.columns("custid") ' 又は Dim columns(1) As DataColumn columns(0) = worktable.columns("custid") worktable.primarykey = columns worktable.primarykey = new DataColumn[] worktable.columns["custid"]; // 又は DataColumn[] columns = new DataColumn[1]; columns[0] = worktable.columns["custid"]; worktable.primarykey = columns; 2 つの列を主キーと仕て定義する例を次に示す worktable.primarykey = New DataColumn( ) worktable.columns("custlname"), _ worktable.columns("custfname") ' 又は Dim keycolumn(2) As DataColumn keycolumn(0) = worktable.columns("custlname") keycolumn(1) = worktable.columns("custfname") worktable.primarykey = keycolumn worktable.primarykey = new DataColumn[] worktable.columns["custlname"], worktable.columns["custfname"]; -44-
45 // 又は DataColumn[] keycolumn = new DataColumn[2]; keycolumn[0] = worktable.columns["custlname"]; keycolumn[1] = worktable.columns["custfname"]; worktable.primarykey = keycolumn; テーブルへの制約の追加 制約を使用すると データの整合性を維持する為に DataTable のデータを強制的に制限出来る 制約は 1 つの列 又は 関連付けられた複数の列に対して自動的に適用される規則で有り 行の値が何等かの方法で変更された時に実行されるアクションを決定する 制約は DataSet の EnforceConstraints プロパティを true に設定した時に適用される ADO.NET には ForeignKeyConstraint と UniqueConstraint の 2 種類の制約が有る 既定では DataRelation を DataSet に追加して複数のテーブル間のリレーションシップを作成すると 此の 2 種類の制約が両方共自動的に作成される 但し リレーションの作成時に createconstraints = false と指定する事に依り 此の動作を無効に出来る ForeignKeyConstraint ForeignKeyConstraint は 関連付けられて居るテーブルに更新や削除を反映させる方法に付いての規則を適用する 例えば 或るテーブルの行の値が更新や削除され 其の同じ値が 関連付けられて居る別のテーブルでも使用されて居る場合 関連付けられて居るテーブル内で実行されるアクションは ForeignKeyConstraint に依って決定される ForeignKeyConstraint の DeleteRule プロパティと UpdateRule プロパティは ユーザーが関連付けられて居るテーブルの行を削除 又は 更新しようと仕た時に実行されるアクションを定義する ForeignKeyConstraint の DeleteRule プロパティと UpdateRule プロパティに使用出来る様々な設定の説明を次の表に示す 規則の設定 説明 Cascade 関連付けられて居る行を削除 更新する SetNull 関連付けられて居る行の値を DBNull に設定する SetDefault 関連付けられて居る行の値を既定値に設定する None 関連付けられて居る行に対してアクションは実行しない ( 既定値 ) ForeignKeyConstraint は 関連付けられて居る行への変更を制限したり 反映させたり出来る 列の ForeignKeyConstraint に対して設定されたプロパティに依っては DataSet の EnforceConstraints プロパティが true で有る場合に親の行に対して操作を実行すると 例外が発生する事が有る 例えば ForeignKeyConstraint の DeleteRule プロパティが None の場合 子の行を持って居る親の行は削除出来ない ForeignKeyConstraint コンストラクタを使用すると 単一列間や列配列間の外部キー制約を作成出来る ConstraintCollection の 1 つで有る テーブルの Constraints プロパティの Add メソッドに結果の ForeignKeyConstraint オブジェクトを渡す コンストラクタ引数を ConstraintCollection の Add メソッドの幾つかのオーバーロードに渡す事に依り ForeignKeyConstraint を作成する事も出来る ForeignKeyConstraint を作成する時に DeleteRule の値と UpdateRule の値を引数と仕てコンストラクタに渡したり 其等の値を次の例に示す様にプロパティと仕て設定したり出来る 此の例では DeleteRule の値が None に設定されて居る -45-
46 Dim custorderfk As ForeignKeyConstraint = New ForeignKeyConstraint("CustOrderFK", _ custds.tables("custtable").columns("customerid"), _ custds.tables("orderstable").columns("customerid")) custorderfk.deleterule = Rule.None ' Cannot delete a customer value that has associated existing orders. custds.tables("orderstable").constraints.add(custorderfk) ForeignKeyConstraint custorderfk = new ForeignKeyConstraint("CustOrderFK", custds.tables["custtable"].columns["customerid"], custds.tables["orderstable"].columns["customerid"]); custorderfk.deleterule = Rule.None; // Cannot delete a customer value that has associated existing orders. custds.tables["orderstable"].constraints.add(custorderfk); AcceptRejectRule 行への変更は AcceptChanges メソッドを使用して受け入れる事が出来 DataSet DataTable 又は DataRow の RejectChanges メソッドを使用してキャンセル出来る DataSet に ForeignKeyConstraints が含まれて居る場合は AcceptChanges メソッドや RejectChanges メソッドを呼び出すと AcceptRejectRule が強制適用される ForeignKeyConstraint の AcceptRejectRule プロパティは 親の行に対して AcceptChanges 又は RejectChanges が呼び出された時に 子の行に対して実行されるアクションを決定する AcceptRejectRule に使用出来る設定の一覧を次の表に示す 規則の設定 説明 Cascade 子の行への変更を受け入れるか 又は 拒否する None 子の行に対してアクションは実行しない ( 既定値 ) UniqueConstraint UniqueConstraint オブジェクトは DataTable 内の 1 つの列や列の配列に対して割り当てる事が出来 指定された列内の総てのデータが行毎に一意に成る様にする UniqueConstraint コンストラクタを使用して 1 つの列や列の配列に対する UNIQUE 制約を作成出来る ConstraintCollection の 1 つで有るテーブルの Constraints プロパティの Add メソッドに結果の UniqueConstraint オブジェクトを渡す コンストラクタ引数を ConstraintCollection の Add メソッドの幾つかのオーバーロードに渡す事に依り UniqueConstraint を作成する事も出来る 1 つの列や複数の列に対して UniqueConstraint を作成する時は オプションで 其の列や複数の列を主キーにするか何うかを指定出来る 列の Unique プロパティを true に設定する事に依り 1 つの列に対する UNIQUE 制約を作成する事も出来る 亦 1 つの列の Unique プロパティを false に設定する事に依り 既存の UNIQUE 制約を削除出来る 1 つの列 ( 又は 複数の列 ) をテーブルの主キーと仕て定義すると 指定した列 ( 又は 複数の列 ) の UNIQUE 制約が自動的に作成される DataTable の PrimaryKey プロパティから列を削除すると UniqueConstraint が削除される DataTable の 2 つの列の UniqueConstraint を作成する例を次に示す Dim custtable As DataTable = custds.tables("customers") Dim custunique As UniqueConstraint = _ New UniqueConstraint(New DataColumn( ) custtable.columns("customerid"), _ custtable.columns("companyname")) -46-
47 custds.tables("customers").constraints.add(custunique) DataTable custtable = custds.tables["customers"]; UniqueConstraint custunique = new UniqueConstraint(new DataColumn[] custtable.columns["customerid"], custtable.columns["companyname"]); custds.tables["customers"].constraints.add(custunique); DataTable 内のデータの操作 DataSet 内に DataTable を作成した後で データベース内のテーブルを使用する場合と同じ操作を実行出来る テーブル内のデータの追加 表示 編集 及び 削除を実行したり エラーとイベントを監視したり テーブル内のデータを照会したり出来る DataTable 内のデータを変更する時には 変更が正確か何うかを検証したり 変更をプログラムに依って受け入れるか 又は 拒否するかを決定したりする事も出来る テーブルへのデータの追加 DataTable を作成し 列と制約を使用して其のテーブルの構造を定義した後で テーブルに新しいデータ行を追加出来る 新しい行を追加するには 新しい変数を DataRow 型と仕て宣言する NewRow メソッドを呼び出すと 新しい DataRow オブジェクトが返される 次に DataTable は DataColumnCollection での定義に従って テーブルの構造に基づいて DataRow オブジェクトを作成する NewRow メソッドを呼び出して新しい行を作成する例を次に示す Dim workrow As DataRow = worktable.newrow( ) DataRow workrow = worktable.newrow( ); 其の後でインデックス 又は 列名を使用して 新しく追加した行を操作する例を次に示す workrow("custlname") = "Smith" workrow(1) = "Smith" workrow["custlname"] = "Smith"; workrow[1] = "Smith"; 新しい行にデータを挿入した後で Add メソッドを使用して DataRowCollection に行を追加するコードを次に示す worktable.rows.add(workrow) worktable.rows.add(workrow); Add メソッドを呼び出して Object 型の値の配列を渡す事に依り 新しい行を追加する別例を次に示す worktable.rows.add(new Object( ) 1, "Smith") worktable.rows.add(new Object[] 1, "Smith"); -47-
48 Object 型の値の配列を Add メソッドに渡すと テーブル内に新しい行が作成され 其の行の列値がオブジェクト配列の値に設定される 配列内の値は テーブル内での列の順序に基づいて 列に順次的に割り当てられる 新しく作成した Customers テーブルに 10 行を追加する例を次に示す Dim workrow As DataRow Dim i As Integer For i = 0 To 9 workrow = worktable.newrow( ) workrow(0) = i workrow(1) = "CustName" & I.ToString( ) worktable.rows.add(workrow) Next DataRow workrow; for (int i = 0; i <= 9; i++) workrow = worktable.newrow( ); workrow[0] = i; workrow[1] = "CustName" + i.tostring( ); worktable.rows.add(workrow); テーブル内のデータの表示 DataTable の内容には DataTable の Rows コレクションと Columns コレクションを使用してアクセス出来る 亦 Select メソッドを使用すると 検索条件 並替順序 行の状態等の基準に基づいて DataTable 内のデータのサブセットを返す事が出来る 更に 主キー値を使用して特定の行を検索する時は DataRowCollection の Find メソッドを使用出来る DataTable オブジェクトの Select メソッドは 指定された基準と一致する DataRow オブジェクトのセットを返す Select は フィルタ式 並替式 及び DataViewRowState のオプション引数を受け取る フィルタ式は DataColumn 値に基づいて返す行を識別する LastName = 'Smith' 等の式で有る並替式は 列の並替に付いての標準 SQL 規則に基づく LastName ASC, FirstName ASC 等の式で有る式の記述の規則に付いては DataColumn クラスの Expression プロパティの資料を参照され度い ヒント :DataTable の Select メソッドへの呼出を多数実行する場合は 最初に DataTable の DataView を作成する事に依り パフォーマンスを向上させる事が出来る DataView を作成すると テーブルの行にインデックスが付けられる Select メソッドが此のインデックスを使用すると クエリ結果を生成する迄の時間が大幅に減少する DataTable の DataView を作成する方法に付いては DataView の作成と使用 を参照され度い Select メソッドは DataViewRowState に基づいて 表示や操作する行のバージョンを判断する 有効な DataViewRowState 列挙値の説明を次の表に示す DataViewRowState の値 CurrentRows Deleted ModifiedCurrent 説明変更されて居ない行 追加された行 及び 変更された行を含む現在の行 削除された行 元のデータを変更した後のバージョンで有る現在のバージョン ModifiedOriginal を参照され度い -48-
49 ModifiedOriginal Added None OriginalRows Unchanged 変更された総ての行の元のバージョン 現在のバージョンは ModifiedCurrent を使用して取得出来る 新しい行 無し 変更されて居ない行 及び 削除された行を含む元の行 変更されて居ない行 DataSet オブジェクトをフィルタ処理して DataViewRowState が CurrentRows に設定されて居る行丈を操作出来る様にする例を次に示す Dim column As DataColumn Dim row As DataRow Dim currentrows( ) As DataRow = _ worktable.select(nothing, Nothing, DataViewRowState.CurrentRows) If (currentrows.length < 1 ) Then Console.WriteLine("No Current Rows Found") Else For Each column in worktable.columns Console.Write(vbTab & column.columnname) Next Console.WriteLine(vbTab & "RowState") For Each row In currentrows For Each column In worktable.columns Console.Write(vbTab & row(column).tostring( )) Next Dim rowstate As String = _ System.Enum.GetName(row.RowState.GetType( ), row.rowstate) Console.WriteLine(vbTab & rowstate) Next End If DataRow[] currentrows = worktable.select(null, null, DataViewRowState.CurrentRows); if (currentrows.length < 1 ) Console.WriteLine("No Current Rows Found"); else foreach (DataColumn column in worktable.columns) Console.Write(" t0", column.columnname); Console.WriteLine(" trowstate"); foreach (DataRow row in currentrows) foreach (DataColumn column in worktable.columns) Console.Write(" t0", row[column]); Console.WriteLine(" t" + row.rowstate); Select メソッドを使用して 異なる RowState 値やフィールド値を持つ行を返す事も出来る 削除された総ての行を参照する DataRow 配列を返し 亦 CustLName を基準にして並べ替えた CustID 列が 5-49-
50 より大きい総ての行を参照する 別の DataRow 配列も返す例を次に示す Deleted 行の情報を表示する方法に付いては 行の状態とバージョン を参照され度い ' Retrieve all deleted rows. Dim deletedrows( ) As DataRow = worktable.select(nothing, Nothing, DataViewRowState.Deleted) ' Retrieve rows where CustID > 5, and order by CustLName. Dim custrows( ) As DataRow = worktable.select("custid > 5", "CustLName ASC") // Retrieve all deleted rows. DataRow[] deletedrows = worktable.select(null, null, DataViewRowState.Deleted); // Retrieve rows where CustID > 5, and order by CustLName. DataRow[] custrows = worktable.select("custid > 5", "CustLName ASC"); Load メソッドの使用 Load メソッドを使用して データソースの行を DataTable に読み込む事が出来る 此れはオーバーロードされたメソッドで 最も単純な形式で単一の DataReader パラメータを受け取る 此の形式に依り 此のメソッドは DataTable に対する行の読み込み而巳を行う 或るいは LoadOption パラメータを指定して DataTable へのデータの追加方法を制御する事も出来る LoadOption パラメータは DataTable にデータの行が既に含まれて居る場合に特に役立つ 其れは 此のパラメータに依って データソースから読み込まれるデータとテーブル内に既に存在するデータを組み合わせる方法が指定されて居る為で有る例えば PreserveCurrentValues( 既定値 ) は DataTable の行が Added と仕てマークされ データソースの行に一致する内容に対して Original 値や各列が設定されて居る場合に指定する Current 値は 行が追加された時に割り当てられた値が保持され 其の行の RowState は Changed に設定される LoadOption 列挙値の簡単な説明を次の表に示す LoadOption の値 OverwriteRow PreserveCurrentValues ( 既定値 ) UpdateCurrentValues 説明読み込まれる行と DataTable に既に存在する行で PrimaryKey 値が同じ場合 各列の Original 値と Current 値は読み込まれる行の値に置き換えられ RowState プロパティは Unchanged に設定される DataTable に存在して居なかった行がデータソースから読み込まれ 其の行の RowState 値は Unchanged に設定される 此のオプションは DataTable の内容を更新して データソースの内容と一致する様にする 読み込まれる行と DataTable に既に存在する行の PrimaryKey 値が同じ場合 Original 値には読み込まれる行の内容が設定されるが Current 値は変更されない RowState が Added 又は Modified の場合 此の値は Modified に設定される RowState が Deleted で有った場合 此の値は Deleted の儘と成る DataTable に存在して居なかった行がデータソースから読み込まれ 其の行の RowState は Unchanged に設定される 読み込まれる行と DataTable に既に存在する行の PrimaryKey 値が同じ場合 Current 値が Original 値にコピーされ Current 値には読み込まれる行の内容が設定される DataTable の RowState が Added の場合 RowState は Added の儘と成る Modified 又は Deleted と仕てマークされた行の RowState は Modified に成る DataTable に存在して居なかった行がデータソースから読み込まれ 其の行の RowState は Added に設定される -50-
51 Load メソッドを使用して Northwind データベースに従業員の誕生日リストを表示する例を次に示す Private Sub LoadBirthdays(ByVal connectionstring As String) ' Assumes that connectionstring is a valid connection string ' to the Northwind database on SQL Server. Dim querystring As String = _ "SELECT LastName, FirstName, BirthDate " & _ " FROM dbo.employees " & _ "ORDER BY BirthDate, LastName, FirstName" ' Open and fill a DataSet. Dim adapter As SqlDataAdapter = New SqlDataAdapter( _ querystring, connectionstring) Dim employees As New DataSet adapter.fill(employees, "Employees") ' Create a SqlDataReader for use with the Load Method. Dim reader As DataTableReader = employees.getdatareader( ) ' Create an instance of DataTable and assign the first ' DataTable in the DataSet.Tables collection to it. Dim datatableemp As DataTable = employees.tables(0) ' Fill the DataTable with data by calling Load and passing the SqlDataReader. datatableemp.load(reader, LoadOption.OverwriteRow) ' Loop through the rows collection and display the values in the console window. Dim employeerow As DataRow For Each employeerow In datatableemp.rows Console.WriteLine("0:MM dd yyyy" & ControlChars.Tab & "1, 2", _ employeerow("birthdate"), _ employeerow("lastname"), _ employeerow("firstname")) Next employeerow ' Keep the window opened to view the contents. Console.ReadLine( ) End Sub テーブル内のデータの編集 DataRow 内の列値を変更すると 其の変更は直ぐに行の現在の状態に反映される 次に DataRowState が Modified に設定され DataRow の AcceptChanges メソッドや RejectChanges メソッドを使用して変更が受け入れられるか 又は 拒否される DataRow は 行の編集中に 其の行の状態を保留に仕て置く為に使用出来る 3 つのメソッドも提供する 此等のメソッドとは BeginEdit EndEdit 及び CancelEdit で有る DataRow の列値が直接変更されると DataRow は Current Default Original の各行バージョンを使用して列値を管理する BeginEdit EndEdit CancelEdit の各メソッドでは 此等の行バージョンに加えて 4 番目の行バージョン Proposed を使用する 行バージョンの詳細に付いては 行の状態とバージョン を参照され度い Proposed 行バージョンは 編集操作中に存在するバージョンで有る編集操作は BeginEdit への呼出 -51-
52 に依って開始し EndEdit 又は CancelEdit の使用 或るいは AcceptChanges 又は RejectChanges の呼出に依って終了する 編集操作中に DataTable の ColumnChanged イベントで ProposedValue を評価する事に依り 個々の列に検証ロジックを適用出来る ColumnChanged イベントは 変更されて居る列への参照と ProposedValue への参照を維持する DataColumnChangeEventArgs を保持する 提示された値を評価した後で 値を変更するか 又は 編集をキャンセル出来る 編集が終了すると 行は Proposed 状態ではなく成る EndEdit を呼び出すと編集内容を確定出来 CancelEdit を呼び出すと編集内容をキャンセル出来る EndEdit は編集内容を確定するが DataSet は AcceptChanges が呼び出される迄は実際には変更を受け入れない 亦 EndEdit 又は CancelEdit を使用して編集を終了する前に AcceptChanges を呼び出した場合は 編集が終了し Proposed 行値が Current 行バージョンと Original 行バージョンの両方に受け入れられる 同様に RejectChanges を呼び出した場合も編集が終了し Current 行バージョンと Proposed 行バージョンの両方が破棄される AcceptChanges 又は RejectChanges を呼び出した後で EndEdit 又は CancelEdit を呼び出しても 編集が既に終了して居る為 其の呼出は無効に成る BeginEdit EndEdit 及び CancelEdit を使用する方法を次の例に示す 此の例では ColumnChanged イベントで ProposedValue をチェックして 編集をキャンセルするか何うかを決定して居る Dim worktable As DataTable = New DataTable worktable.columns.add("lastname", Type.GetType("System.String")) AddHandler worktable.columnchanged, _ New DataColumnChangeEventHandler(AddressOf OnColumnChanged) Dim workrow As DataRow = worktable.newrow( ) workrow(0) = "Smith" worktable.rows.add(workrow) workrow.beginedit( ) ' Causes the ColumnChanged event to write a message and cancel the edit. workrow(0) = "" workrow.endedit( ) ' Displays "Smith, New". Console.WriteLine("0, 1", workrow(0), workrow.rowstate) Private Shared Sub OnColumnChanged( sender As Object, args As DataColumnChangeEventArgs) If args.column.columnname = "LastName" Then If args.proposedvalue.tostring( ) = "" Then Console.WriteLine("Last Name cannot be blank.edit canceled.") args.row.canceledit( ) End If End If End Sub DataTable worktable= new DataTable( ); worktable.columns.add("lastname", typeof(string)); worktable.columnchanged += new DataColumnChangeEventHandler(OnColumnChanged); -52-
53 DataRow workrow = worktable.newrow( ); workrow[0] = "Smith"; worktable.rows.add(workrow); workrow.beginedit( ); // Causes the ColumnChanged event to write a message and cancel the edit. workrow[0] = ""; workrow.endedit( ); // Displays "Smith, New". Console.WriteLine("0, 1", workrow[0], workrow.rowstate); protected static void OnColumnChanged(Object sender, DataColumnChangeEventArgs args) if (args.column.columnname == "LastName") if (args.proposedvalue.tostring( ) == "") Console.WriteLine("Last Name cannot be blank. Edit canceled."); args.row.canceledit( ); 行の状態とバージョン ADO.NET は 行の状態とバージョンを使用してテーブル内の行を管理する 行状態は 1 つの行のステータスを示す 行バージョンは 1 つの行の値が変更される時に 変更に応じて其の行に格納される現在の値 元の値 既定値等を維持する 例えば 或る行の 1 つの列を変更すると 此の行の状態は Modified に成り 次の 2 つの行バージョンが存在する事に成る Current には現在の行値が格納され Original には其の列が変更される前の行値が格納される 各 DataRow オブジェクトに有る RowState プロパティを調べると 行の現在の状態を確認出来る 各 RowState 列挙値の簡単な説明を次の表に示す RowState の値 Unchanged Added Modified Deleted Detached 説明 AcceptChanges が最後に呼び出されてから 又は DataAdapter.Fill に依って行が作成されてから変更は行われて居ない 行がテーブルに追加されたが AcceptChanges が呼び出されて居ない 行の幾つかの要素が変更された 行がテーブルから削除されたが AcceptChanges が呼び出されて居ない 行が何の DataRowCollection にも属して居ない 新しく作成された行の RowState は Detached に設定される Add メソッドを呼び出して新しい DataRow を DataRowCollection に追加すると RowState プロパティの値は Added に設定される Detached は Remove メソッドを使用するか 又は Delete メソッドに続いて AcceptChanges メソッドを使用して DataRowCollection から削除された行に対しても設定される DataSet DataTable 又は DataRow に対して AcceptChanges が呼び出されると Deleted の行状態を持つ総ての行が削除される 残りの行状態は Unchanged に成り Original 行バージョンの値は Current 行バージョンの値で上書きされる RejectChanges が呼び出されると Added の行状態を持つ総ての行が削除される 残りの行の行状態は Unchanged に成り Current 行バージョンの値は Original 行バージョンの値で上書きされる -53-
54 DataRowVersion パラメータと列参照を渡す事に依り 或る行の行バージョンを表示する例を次に示す Dim custrow As DataRow = custtable.rows(0) Dim custid As String = custrow("customerid", DataRowVersion.Original).ToString( ) DataRow custrow = custtable.rows[0]; string custid = custrow["customerid", DataRowVersion.Original].ToString( ); 各 DataRowVersion 列挙値の簡単な説明を次の表に示す DataRowVersion の値 Current Default Original Proposed 説明行の現在の値 此の行バージョンは Deleted の RowState を持つ行に付いては存在しない 特定の行の既定の行バージョン Added Modified 又は Unchanged 行の既定の行バージョンは Current で有る Deleted 行の既定の行バージョンは Original で有る Detached 行の既定の行バージョンは Proposed で有る 行の元の値 此の行バージョンは Added の RowState を持つ行に付いては存在しない 行に対して提示された値 此の行バージョンは 行 詰まり DataRowCollection の一部ではない行に対する編集操作の間存在する HasVersion メソッドを呼び出して DataRowVersion を引数と仕て渡す事に依り DataRow が特定の行バージョンを持って居るか何うかを確認出来る 例えば 下記は 新しく追加された行に対して AcceptChanges が呼び出されて居ない場合に false を返す DataRow.HasVersion(DataRowVersion.Original) テーブルから削除された総ての行の値を表示するコード例を次に示す Deleted 行には Current 行バージョンが無い為 列値にアクセスする時には DataRowVersion.Original を渡す必要が有る Dim cattable As DataTable = catds.tables("categories") Dim delrows( ) As DataRow = cattable.select(nothing, Nothing, DataViewRowState.Deleted) Console.WriteLine("Deleted rows:" & vbcrlf) Dim catcol As DataColumn Dim delrow As DataRow For Each catcol In cattable.columns Console.Write(catCol.ColumnName & vbtab) Next Console.WriteLine( ) For Each delrow In delrows For Each catcol In cattable.columns Console.Write(delRow(catCol, DataRowVersion.Original) & vbtab) Next Console.WriteLine( ) Next -54-
55 DataTable cattable = catds.tables["categories"]; DataRow[] delrows = cattable.select(null, null, DataViewRowState.Deleted); Console.WriteLine("Deleted rows: n"); foreach (DataColumn catcol in cattable.columns) Console.Write(catCol.ColumnName + " t"); Console.WriteLine( ); foreach (DataRow delrow in delrows) foreach (DataColumn catcol in cattable.columns) Console.Write(delRow[catCol, DataRowVersion.Original] + " t"); Console.WriteLine( ); テーブルからの行の削除 DataTable オブジェクトから DataRow オブジェクトを削除するには DataRowCollection オブジェクトの Remove メソッドと DataRow オブジェクトの Delete メソッドの 2 つのメソッドを使用出来る Remove メソッドは DataRowCollection から DataRow を削除するが 一方の Delete メソッドは削除対象の行をマークする丈で有る 実際の削除は アプリケーションが AcceptChanges メソッドを呼び出すと実行される Delete を使用すると 行を実際に削除する前に 削除対象と仕て何の行がマークされて居るかをプログラムに依ってチェック出来る 削除対象と仕てマークされて居る行の RowState プロパティは Deleted に設定される DataAdapter 及び リレーショナルデータソースに関連して DataSet や DataTable を使用する時は DataRow の Delete メソッドを使用して行を削除する Delete メソッドは DataSet や DataTable の行を Deleted と仕てマークするが 其の行を削除しない 代わりに DataAdapter が Deleted と仕てマークされた行を検出した時に DeleteCommand メソッドを実行して データソースの該当する行を削除する 其の後 AcceptChanges メソッドを使用して 其の行を永続的に削除出来る Remove を使用して行を削除すると 行はテーブルから完全に削除されるが DataAdapter はデータソースの該当する行を削除しない DataRowCollection の Remove メソッドが DataRow を引数と仕て受け取り 其の行をコレクションから削除する例を次に示す worktable.rows.remove(workrow) worktable.rows.remove(workrow); 此れに対して DataRow の Delete メソッドを呼び出して 該当する行の RowState を Deleted に変更する例を次に示す workrow.delete workrow.delete( ); 行を削除対象と仕てマークしてから DataTable オブジェクトの AcceptChanges メソッドを呼び出すと -55-
56 其の行が DataTable から削除される 此れに対して RejectChanges を呼び出すと 行の RowState は其の行が Deleted と仕てマークされる前の状態に戻る メモ : DataRow の RowState が Added で有る場合 詰まり テーブルに行が追加された直後の状態の場合に 其の行を Deleted と仕てマークすると 其の行はテーブルから削除される 行のエラー情報の追加と読み取り DataTable の値を編集して居る時に 行エラーに対処する必要を無くす為に エラー情報を行に追加して後で使用する事が出来る DataRow オブジェクトは 此の目的の為に各行に RowError プロパティを提供する DataRow の RowError プロパティにデータを追加すると 其の DataRow の HasErrors プロパティが true に設定される DataRow が DataTable の一部で有り DataRow.HasErrors が true で有る場合は DataTable.HasErrors プロパティも true に成る 此の原則は DataTable が属して居る DataSet に対しても適用される エラーの有無を確認する場合は HasErrors プロパティをチェックして エラー情報が追加された行が有るか何うかを判断出来る HasErrors が true の場合に DataTable の GetErrors メソッドを使用して エラーの有る行丈を返してチェックする例を次に示す Dim worktable As DataTable = New DataTable("Customers") worktable.columns.add("custid", Type.GetType("System.Int32")) worktable.columns.add("total", Type.GetType("System.Double")) AddHandler worktable.rowchanged, _ New DataRowChangeEventHandler(AddressOf OnRowChanged) Dim i As Int32 For i= 0 To 10 worktable.rows.add(new Object( ) i, i *100) Next If worktable.haserrors Then Console.WriteLine("Errors in Table " & worktable.tablename) Dim myrow As DataRow For Each myrow In worktable.geterrors( ) Console.WriteLine("CustID = " & myrow("custid").tostring( )) Console.WriteLine(" Error = " & myrow.rowerror & vbcrlf) Next End If Private Shared Sub OnRowChanged(sender As Object, args As DataRowChangeEventArgs) ' Check for zero values. If CDbl(args.Row("Total")) = 0 Then args.row.rowerror = "Total cannot be 0." End Sub DataTableworkTable = new DataTable("Customers"); worktable.columns.add("custid", typeof(int32)); worktable.columns.add("total", typeof(double)); worktable.rowchanged += new DataRowChangeEventHandler(OnRowChanged); for (int i = 0; i < 10; i++) worktable.rows.add(new Object[] i, i*100); -56-
57 if (worktable.haserrors) Console.WriteLine("Errors in Table " + worktable.tablename); foreach (DataRow myrow in worktable.geterrors( )) Console.WriteLine("CustID = " + myrow["custid"]); Console.WriteLine(" Error = " + myrow.rowerror + " n"); protected static void OnRowChanged(Object sender, DataRowChangeEventArgs args) // Check for zero values. if (args.row["total"].equals(0d)) args.row.rowerror = "Total cannot be 0."; 行への変更の受入と拒否 DataTable 内のデータに行われた変更が正確で有るか何うかを検証した後で DataRow DataTable 又は DataSet の AcceptChanges メソッドを使用して 変更を受け入れる事が出来る 変更を受け入れると Current 行値が Original 値に設定され RowState プロパティが Unchanged に設定される 変更を受け入れるか 又は 拒否すると RowError 情報が削除され HasErrors プロパティが false に設定される 変更を受け入れるか 又は 拒否した場合 データソース内で実行中の更新操作にも影響する事が有る 詳細に付いては DataAdapter に依るデータソースの更新 を参照され度い DataTable に外部キー制約が存在する場合 AcceptChanges と RejectChanges を使用して受け入れられた変更 又は 拒否された変更は ForeignKeyConstraint.AcceptRejectRule に基づいて DataRow の子の行に反映される 詳細に付いては テーブルへの制約の追加 を参照され度い 行にエラーが有るか何うかをチェックし 必要に応じてエラーを解決し エラーを解決出来ない場合には其の行を拒否する例を次に示す 解決されたエラーに付いては RowError 値が空の文字列にリセットされる為 HasErrors プロパティが false に設定される エラーの有る行が総て解決又は拒否された時点で DataTable 全体に対する総ての変更を受け入れる為に AcceptChanges が呼び出される If worktable.haserrors Then Dim errrow As DataRow For Each errrow in worktable.geterrors( ) If errrow.rowerror = "Total cannot exceed 1000." Then errrow("total") = 1000 errrow.rowerror = ""' Clear the error. Else errrow.rejectchanges( ) End If Next End If worktable.acceptchanges( ) if (worktable.haserrors) foreach (DataRow errrow in worktable.geterrors( )) -57-
58 if (errrow.rowerror == "Total cannot exceed 1000.") errrow["total"] = 1000; errrow.rowerror = "";// Clear the error. else errrow.rejectchanges( ); worktable.acceptchanges( ); DataTable イベントの使用 DataTable オブジェクトは アプリケーションが処理出来る一連のイベントを提供する DataTable イベントの説明を次の表に示す イベント ColumnChanged ColumnChanging RowChanged RowChanging RowDeleted RowDeleting 説明値が列に正常に挿入された時に発生する 列に対して値が提示された時に発生する テーブル内の行が正常に編集された後に発生する テーブル内の行が変更される時に発生する テーブル内の行が Deleted とマークされた後に発生する テーブル内の行が Deleted と仕てマークされる前に発生する 4 つのイベント OnColumnChanged OnColumnChanging OnRowChanged 及び OnRowChanging を作成する例を次に示す 此等の各イベントは 列や行が変更される時に発生する AddHandler worktable.columnchanged, New _ DataColumnChangeEventHandler(AddressOf OnColumnChanged) AddHandler worktable.columnchanging, New _ DataColumnChangeEventHandler(AddressOf OnColumnChanging) AddHandler worktable.rowchanged, New _ DataRowChangeEventHandler(AddressOf OnRowChanged) AddHandler worktable.rowchanging, New _ DataRowChangeEventHandler(AddressOf OnRowChanging) Private Shared Sub OnColumnChanged(sender As Object, args As DataColumnChangeEventargs) Console.Write(" ColumnChanged: ") Console.Write(args.Column.ColumnName & " changed to '" & _ args.proposedvalue.tostring( ) & "'" & vbcrlf) End Sub Private Shared Sub OnColumnChanging(sender As Object, args As DataColumnChangeEventargs) Console.Write("ColumnChanging: ") Console.Write(args.Column.ColumnName & " equals '" & _ args.row(args.column).tostring( ) & _ "', changing to '" & args.proposedvalue.tostring( ) & "'" & vbcrlf) End Sub Private Shared Sub OnRowChanging(sender As Object, args As DataRowChangeEventargs) -58-
59 If args.action <> DataRowAction.Nothing Then Dim actionstr As String actionstr = System.Enum.GetName(args.Action.GetType( ), args.action) Console.WriteLine(" RowChanging: Action = " & actionstr & ", _ CustID = " & args.row("custid").tostring( )) End If End Sub Private Shared Sub OnRowChanged(sender As Object, args As DataRowChangeEventargs) If args.action <> DataRowAction.Nothing Then Dim actionstr As String actionstr = System.Enum.GetName(args.Action.GetType( ), args.action) Console.WriteLine("RowChanged: Action = " & actionstr & ", _ CustID = " & args.row("custid").tostring( )) End If End Sub worktable.columnchanged+= new DataColumnChangeEventHandler(OnColumnChanged); worktable.columnchanging += new DataColumnChangeEventHandler(OnColumnChanging); worktable.rowchanged += new DataRowChangeEventHandler(OnRowChanged); worktable.rowchanging += new DataRowChangeEventHandler(OnRowChanging); protected static void OnColumnChanged(object sender, DataColumnChangeEventArgs args) Console.Write(" ColumnChanged: "); Console.Write(args.Column.ColumnName + " changed to '" + args.proposedvalue + "' n"); protected static void OnColumnChanging(object sender, DataColumnChangeEventArgs args) Console.Write("ColumnChanging: "); Console.Write(args.Column.ColumnName + " equals '" + args.row[args.column] + "', changing to '" + args.proposedvalue + "' n"); protected static void OnRowChanging(object sender, DataRowChangeEventArgs args) if (args.action!= DataRowAction.Nothing) Console.WriteLine(" RowChanging: Action = " + args.action + ", CustID = " + args.row["custid"]); protected static void OnRowChanged(object sender, DataRowChangeEventArgs args) if (args.action!= DataRowAction.Nothing) Console.WriteLine("RowChanged: Action = " + args.action + ", CustID = " + args.row["custid"]); DataView の作成と使用 DataView では DataTable に格納されて居るデータの様々なビューを作成出来る 此の機能は データ連結アプリケーションで頻繁に使用される DataView を使用すると 様々な並替順序を使用してテーブルのデータを公開したり 行の状態やフィルタ式に基づいてデータをフィルタ処理したり出来る -59-
60 DataView では 基に成る DataTable のデータの動的ビューが作成される ビューの内容 順序 メンバシップには 変更が反映される 此れは DataTable の Select メソッドとは異なる 此のメソッドでは 特定のフィルタや並替順序毎にテーブルから DataRow 配列が戻される 戻される配列の内容には 基に成るテーブルの変更内容が反映されて居るが メンバシップと順序は静的で有る DataView は動的機能を備えて居る為 データ連結アプリケーションに取って理想的なオブジェクトで有る DataView は 1 つのデータセットの動的ビューで有るデータベースのビューと同様に 此の動的ビューには 様々な並替順序やフィルタ処理条件を適用出来る 但し データベースビューとは異なり DataView は テーブルと仕ては処理出来ず 結合テーブルのビューも作成出来ない 亦 ソーステーブルの既存の列を除外したり ソーステーブルにない列 ( 計算列等 ) を追加したり出来ない DataSet の総てのテーブルのビュー設定を管理するには DataViewManager を使用する DataViewManager を使用すると 各テーブルの既定のビュー設定を簡単に管理出来る DataSet の複数のテーブルにコントロールを連結する最適な方法は DataViewManager に連結する方法で有る DataView の作成 DataView は 2 通りの方法で作成出来る DataView コンストラクタを使用するか 又は DataTable の DefaultView プロパティへの参照を作成する 空の DataView コンストラクタを使用出来る 亦 DataView コンストラクタでは DataTable を 1 つの引数と仕て取るか 又は フィルタ条件 並替条件 及び 行状態フィルタと共に DataTable を使用する DataView で使用出来る其の他の引数に付いては DataView を使用したデータの並替とフィルタ処理 を参照され度い DataView のインデックスが作成されるのは DataView が作成される時点と Sort RowFilter 又は RowStateFilter の各プロパティが変更される時点で有る為 DataView の作成時に初期の並替順序や初期フィルタ条件をコンストラクタ引数と仕て指定すると パフォーマンスを最大限に引き出す事が出来る 並替条件やフィルタ条件を指定せずに DataView を作成してから Sort RowFilter 又は RowStateFilter の各プロパティを設定すると インデックスが少なくとも 2 回作成される 此れは DataView の作成時点と 並替プロパティやフィルタプロパティの変更時で有る 引数を取らないコンストラクタを使用して DataView を作成すると Table プロパティを設定して居ない間は DataView が使用出来る DataView コンストラクタを使用して DataView を作成するコード例を次に示す DataTable と共に RowFilter Sort 列 及び DataViewRowState が指定されて居る Dim custdv As DataView = New DataView(custDS.Tables("Customers"), _ "Country = 'USA'", "ContactName", DataViewRowState.CurrentRows) DataView custdv = new DataView(custDS.Tables["Customers"], "Country = 'USA'", "ContactName", DataViewRowState.CurrentRows); テーブルの DefaultView プロパティを使用して DataTable の既定の DataView への参照を取得するコード例を次に示す Dim custdv As DataView = custds.tables("customers").defaultview DataView custdv = custds.tables["customers"].defaultview; -60-
61 DataView を使用したデータの並替とフィルタ処理 DataView には DataTable のデータの並替とフィルタ処理を行う様々な方法が用意されて居る Sort プロパティを使用すれば 1 列 又は 複数列の並替順序を指定し ASC( 昇順 ) パラメータと DESC( 降順 ) パラメータを含める事が出来る ApplyDefaultSort プロパティを使用すると テーブルの主キー列 (1 列 又は 複数列 ) に基づいて昇順の並替順序を自動的に作成出来る Sort プロパティが null 参照か空の文字列の場合 及び テーブルに主キーが定義されて居る場合は ApplyDefaultSort 丈が適用される RowFilter プロパティを使用すると 列の値に基づいて行のサブセットを指定出来る RowFilter プロパティの有効な式の詳細に付いては DataColumn クラスの Expression プロパティの情報を参照され度い データサブセットの動的ビューの作成とは対照的に データに対して特定のクエリの実行結果を返す場合 パフォーマンスを最大限に引き出すには RowFilter プロパティを設定する代わりに DataView の Find メソッドや FindRows メソッドを使用する RowFilter プロパティを設定すると データのインデックスが再作成され アプリケーションのオーバーヘッドが増加してパフォーマンスの低下を招く RowFilter プロパティは データ連結アプリケーションでの使用に適して居る 此のアプリケーションでは 連結されたコントロールに依ってフィルタ処理結果が表示される Find メソッドと FindRows メソッドでは 現在のインデックスが使用される 此の為 インデックスを再作成する必要は無い Find メソッドと FindRows メソッドの詳細に付いては DataView の検索 を参照され度い RowStateFilter プロパティを使用して 表示する行バージョンを指定出来る DataView は 基に成る行の RowState に従って 暗黙的に行バージョンを公開する 例えば RowStateFilter が DataViewRowState.Deleted に設定されて居る場合 DataView は行バージョンが Original の Deleted 行を総て公開する 此れは Current 行バージョンが存在しない為で有る DataRowView の RowVersion プロパティを使用すると 公開される行のバージョンを確認出来る DataViewRowState のオプションを次の表に示す DataViewRowState のオプション CurrentRows Added Deleted ModifiedCurrent ModifiedOriginal None OriginalRows Unchanged 説明 Current 行バージョンの総ての Unchanged 行 Added 行 及び Modified 行で有る ( 既定値 ) Current 行バージョンの総ての Added 行で有る Original 行バージョンの総ての Deleted 行で有る Current 行バージョンの総ての Modified 行で有る Original 行バージョンの総ての Modified 行で有る 行が無い Original 行バージョンの総ての Unchanged 行 Modified 行 及び Deleted 行で有る Current 行バージョンの総ての Unchanged 行で有る 行状態と行バージョンの詳細に付いては 行の状態とバージョン を参照され度い 在庫数が標準在庫数以下で有る製品を 仕入先 ID(supplier ID) で並べ替え 更に製品名 (product name) で並べ替えたビューを作成するコード例を次に示す Dim prodview As DataView = New DataView(prodDS.Tables("Products"), _ "UnitsInStock <= ReorderLevel", "SupplierID, ProductName", DataViewRowState.CurrentRows) DataView prodview = new DataView(prodDS.Tables["Products"], "UnitsInStock <= ReorderLevel", "SupplierID, ProductName", DataViewRowState.CurrentRows); -61-
62 DataView を使用したデータの表示 DataView は 一般にデータ連結アプリケーションで使用される データ連結アプリケーションでは 基に成るテーブルの内容がコントロールに依ってビューと仕て公開される 以降の資料では DataView の内容をカスタムコントロールに対して公開する方法 データ連結アプリケーション以外のアプリケーションで公開する方法 詰まり DataView で特定の値を検索する方法に付いて説明する 亦 親子のリレーションシップから子データのビューを作成する方法に付いて説明する DataView は DataRowView オブジェクトの列挙可能なコレクションを公開する DataRowView オブジェクトは 基に成るテーブルの列の名前や列の序数参照に依ってインデックスが設定されて居るオブジェクトの配列と仕て値を公開する DataRowView が DataRowView の Row プロパティを使用して公開して居る DataRow にアクセス出来る DataRowView を使用して値を表示して居る場合は DataView の RowStateFilter プロパティに依って 基に成る DataRow から公開される行バージョンが決まる DataRow を使用して様々な行バージョンにアクセスする方法に付いては 行の状態とバージョン を参照され度い テーブルの現在の値と元の値を総て表示するコード例を次に示す Dim catview As DataView = New DataView(catDS.Tables("Categories")) Console.WriteLine("Current Values:") WriteView(catView) Console.WriteLine("Original Values:") catview.rowstatefilter = DataViewRowState.ModifiedOriginal WriteView(catView) Public Shared Sub WriteView(thisDataView As DataView) Dim rowview As DataRowView Dim i As Integer For Each rowview In thisdataview For i = 0 To thisdataview.table.columns.count - 1 Console.Write(rowView(i) & vbtab) Next Console.WriteLine( ) Next End Sub DataView catview = new DataView(catDS.Tables["Categories"]); Console.WriteLine("Current Values:"); WriteView(catView); Console.WriteLine("Original Values:"); catview.rowstatefilter = DataViewRowState.ModifiedOriginal; WriteView(catView); public static void WriteView(DataView thisdataview) foreach (DataRowView rowview in thisdataview) for (int i = 0; i < thisdataview.table.columns.count; i++) Console.Write(rowView[i] + " t"); Console.WriteLine( ); -62-
63 DataView の検索 DataView の Find メソッドと FindRows メソッドを使用すると 並替キーの値に基づいて行を検索出来る Find メソッドと FindRows メソッドに依る検索で 値の大文字と小文字が区別されるか何うかは 基に成る DataTable の CaseSensitive プロパティに依って決まる 検索結果を返すには 検索値が既存の並替キーの値と完全に一致して居る必要が有る Find メソッドは 検索条件に一致する DataRowView のインデックスの整数値を返す 複数の行が検索条件に一致する場合は 一致した最初の DataRowView が返される 一致する DataRowView が無い場合には Find は -1 を返す 複数の行に一致する検索結果を返すには FindRows メソッドを使用する FindRows は Find メソッドと同様に機能するが DataView 内で条件に一致する総ての行を参照する DataRowView 配列を返す点が Find メソッドとは異なる 一致する行が見付からない場合 DataRowView 配列は空に成る Find メソッド 又は FindRows メソッドを使用するには 並替順序を指定する必要が有る 並替順序を指定するには ApplyDefaultSort を true に設定するか 又は Sort プロパティを使用する 並替順序が指定されないと 例外がスローされる Find メソッドと FindRows メソッドには 並替順序に指定されて居る列の数と長さが一致する値配列を入力と仕て渡す 1 つの列に基づく並替の場合は 1 つの値を渡す 複数列に基づく並替の場合は オブジェクトの配列を渡す 複数列に基づく並替では オブジェクト配列の値の順序が DataView の Sort プロパティに指定されて居る列の順序と一致する必要が有る 1 列の並替順序が設定されて居る DataView に対して Find メソッドを呼び出すコード例を次に示す Dim custview As DataView = _ New DataView(custDS.Tables("Customers"), "", _ "CompanyName", DataViewRowState.CurrentRows) Dim rowindex As Integer = custview.find("the Cracker Box") If rowindex = -1 Then Console.WriteLine("No match found.") Else Console.WriteLine("0, 1", _ custview(rowindex)("customerid").tostring( ), _ custview(rowindex)("companyname").tostring( )) End If DataView custview = new DataView(custDS.Tables["Customers"], "", "CompanyName", DataViewRowState.CurrentRows); int rowindex = custview.find("the Cracker Box"); if (rowindex == -1) Console.WriteLine("No match found."); else Console.WriteLine("0, 1", custview[rowindex]["customerid"].tostring( ), custview[rowindex]["companyname"].tostring( )); -63-
64 Sort プロパティで複数の列が指定される場合は 次のコード例に示す様に 各列に対応する検索値を Sort プロパティで指定されて居る順序で格納したオブジェクト配列を渡す必要が有る Dim custview As DataView = _ New DataView(custDS.Tables("Customers"), "", _ "CompanyName, ContactName", DataViewRowState.CurrentRows) Dim foundrows( ) As DataRowView = _ custview.findrows(new object( ) "The Cracker Box", "Liu Wong") If foundrows.length = 0 Then Console.WriteLine("No match found.") Else Dim mydrv As DataRowView For Each mydrv In foundrows Console.WriteLine("0, 1", _ mydrv("companyname").tostring( ), mydrv("contactname").tostring( )) Next End If DataView custview = new DataView(custDS.Tables["Customers"], "", "CompanyName, ContactName", DataViewRowState.CurrentRows); DataRowView[] foundrows = custview.findrows(new object[] "The Cracker Box", "Liu Wong"); if (foundrows.length == 0) Console.WriteLine("No match found."); else foreach (DataRowView mydrv in foundrows) Console.WriteLine("0, 1", mydrv["companyname"].tostring( ), mydrv["contactname"].tostring( )); DataView を使用したリレーションシップ間の移動 DataSet 内のテーブル間にリレーションシップが存在する場合は 此のリレーションシップの子テーブルの行が含まれて居る DataView を作成出来る 此の様な DataView を作成するには 親テーブルの行に対して DataRowView の CreateChildView メソッドを使用する 例えば 次のコードは CategoryName と ProductName に依ってデータをアルファベット順に並べ替えられた Categories と此のテーブルに関連する Products を表示す Dim cattable As DataTable = catds.tables("categories") Dim prodtable As DataTable = catds.tables("products") ' Create a relation between the Categories and Products tables. Dim relation As DataRelation = catds.relations.add("catprodrel", _ cattable.columns("categoryid"), prodtable.columns("categoryid")) ' Create DataViews for the Categories and Products tables. Dim catview As DataView = New DataView(catTable, "", _ "CategoryName", DataViewRowState.CurrentRows) -64-
65 Dim prodview As DataView ' Iterate through the Categories table. Dim catdrv, proddrv As DataRowView For Each catdrv In catview Console.WriteLine(catDRV("CategoryName")) ' Create a DataView of the child product records. prodview = catdrv.createchildview(relation) prodview.sort = "ProductName" For Each proddrv In prodview Console.WriteLine(vbTab & proddrv("productname")) Next Next DataTable cattable = catds.tables["categories"]; DataTable prodtable = catds.tables["products"]; // Create a relation between the Categories and Products tables. DataRelation relation = catds.relations.add("catprodrel", cattable.columns["categoryid"], prodtable.columns["categoryid"]); // Create DataViews for the Categories and Products tables. DataView catview = new DataView(catTable, "", "CategoryName", DataViewRowState.CurrentRows); DataView prodview; // Iterate through the Categories table. foreach (DataRowView catdrv in catview) Console.WriteLine(catDRV["CategoryName"]); // Create a DataView of the child product records. prodview = catdrv.createchildview(relation); prodview.sort = "ProductName"; foreach (DataRowView proddrv in prodview) Console.WriteLine(" t" + proddrv["productname"]); DataView を使用したデータの変更 DataView を使用して データ行を基に成るテーブルに追加 削除 又は 変更出来る 基に成るテーブルのデータを DataView で変更出来るか何うかは DataView の 3 つのブール値プロパティで制御される 此の 3 つのプロパティとは AllowNew AllowEdit AllowDelete で有る 此等のプロパティの既定値は true で有る AllowNew が true の場合は DataView の AddNew メソッドを使用して DataRowView を新規に作成出来る DataRowView の EndEdit メソッドが呼び出される迄は 新規に作成された行は基に成る DataTable に追加されない DataRowView の CancelEdit メソッドが呼び出されると 新規に作成された行は破棄される 一度に編集出来るのは 1 つの DataRowView 丈で有る 保留中の行が有る場合は DataRowView の AddNew メソッドや BeginEdit メソッドを呼び出すと 保留中の行に対して EndEdit が暗黙的に呼び出される EndEdit が呼び出されると 基に成る DataTable に対して変更が適用される 適用された変更をコミットするには DataTable DataSet 又は DataRow の各オブジェクトの AcceptChanges メソッドを使用し 拒否するには此等のオブジェクトの RejectChanges メソッドを使用する AllowNew が false の場合は DataRowView の AddNew メソッドを呼び出すと例外がスローされる -65-
66 AllowEdit が true の場合は DataRowView を使用すると DataRow の内容を変更出来る 基に成る行の変更内容を確定するには DataRowView.EndEdit を使用し 変更内容を取り消すには DataRowView.CancelEdit を使用する 一度に編集出来るのは 1 行丈で有る 保留中の行が有る場合は DataRowView の AddNew メソッドや BeginEdit メソッドを呼び出すと 保留中の行に対して EndEdit が暗黙的に呼び出される EndEdit が呼び出されると 基に成る DataRow の Current 行バージョンに対して変更が適用される 適用された変更をコミットするには DataTable DataSet 又は DataRow の各オブジェクトの AcceptChanges メソッドを使用し 拒否するには此等のオブジェクトの RejectChanges メソッドを使用する AllowEdit が false の場合は DataRowView の値を変更しようとすると例外がスローされる 既存の DataRowView の編集中でも 未だ確定されて居ない変更に関して 基に成る DataTable のイベントが発生する場合が有る DataRowView に対して EndEdit と CancelEdit の孰れが呼び出されて居るかに関係なく 基に成る DataRow に対して EndEdit を呼び出すと 確定されて居ない変更が適用され CancelEdit を呼び出すと 確定されて居ない変更が取り消される AllowDelete が true の場合は DataView オブジェクト 又は DataRowView オブジェクトの Delete メソッドを使用して DataView の行を削除出来る DataView の行を削除すると 基に成る DataTable から行が削除される 後で此の削除操作をコミットするには AcceptChanges を使用し 拒否するには RejectChanges を使用する AllowDelete が false の場合は DataView 又は DataRowView の Delete メソッドを呼び出すと例外がスローされる 次のコード例は DataView を使用して行を削除する機能を無効にし DataView を使用して基に成るテーブルに新しい行を追加する Dim custtable As DataTable = custds.tables("customers") Dim custview As DataView = custtable.defaultview custview.sort = "CompanyName" custview.allowdelete = False Dim newdrv As DataRowView = custview.addnew( ) newdrv("customerid") = "ABCDE" newdrv("companyname") = "ABC Products" newdrv.endedit( ) DataTable custtable = custds.tables["customers"]; DataView custview = custtable.defaultview; custview.sort = "CompanyName"; custview.allowdelete = false; DataRowView newdrv = custview.addnew( ); newdrv["customerid"] = "ABCDE"; newdrv["companyname"] = "ABC Products"; newdrv.endedit( ); DataView イベントの操作 DataView の ListChanged イベントを使用して ビューが更新されて居るか何うかを確認出来る 基に成るテーブルの行の追加 削除 又は 変更や 此のスキーマの列の追加や削除 親子のリレーションシップの変更等 此等の更新を行うと此のイベントが発生する 更に 現在表示されて居る行のリストが新しい並替順序やフィルタの適用に依り大幅に変更された場合 ListChanged イベントは其の事も通知する -66-
67 ListChanged イベントは System.ComponentModel 名前空間の ListChangedEventHandler デリゲートを実装し ListChangedEventArgs オブジェクトを入力と仕て受け取る 発生した変更の内容を確認するには ListChangedEventArgs オブジェクトの ListChangedType プロパティの ListChangedType 列挙値を使用する 行の追加 削除 又は 移動に依る変更の場合 追加された行や移動された行の新しいインデックスと削除された行の古いインデックスには ListChangedEventArgs オブジェクトの NewIndex プロパティを使用してアクセス出来る 移動された行の場合 移動前の古いインデックスにアクセスするには ListChangedEventArgs オブジェクトの OldIndex プロパティを使用する DataViewManager は 更にテーブルが追加や削除された場合に 又は 基に成る DataSet の Relations コレクションが変更された場合に 其の事を通知する為に ListChanged イベントを公開する ListChanged イベントハンドラを追加する方法を次のコード例に示す AddHandler custview.listchanged, _ New System.ComponentModel.ListChangedEventHandler( _ AddressOf OnListChanged) Private Shared Sub OnListChanged( _ sender As Object, args As System.ComponentModel.ListChangedEventArgs) Console.WriteLine("ListChanged:") Console.WriteLine(vbTab & "Type = " & _ System.Enum.GetName(args.ListChangedType.GetType( ), args.listchangedtype)) Console.WriteLine(vbTab & "OldIndex = " & args.oldindex) Console.WriteLine(vbTab & "NewIndex = " & args.newindex) End Sub custview.listchanged+= new System.ComponentModel.ListChangedEventHandler(OnListChanged); protected static void OnListChanged(object sender, System.ComponentModel.ListChangedEventArgs args) Console.WriteLine("ListChanged:"); Console.WriteLine(" ttype = " + args.listchangedtype); Console.WriteLine(" toldindex = " + args.oldindex); Console.WriteLine(" tnewindex = " + args.newindex); DataViewManager を使用した既定のテーブルビューの設定 DataView の総てのテーブルのビュー設定を管理するには DataViewManager を使用する リレーションシップを移動するグリッド等の様に 1 つのコントロールを複数のテーブルに連結する場合は DataViewManager が適して居る DataViewManager には DataSet のテーブルのビュー設定に使用される DataViewSetting オブジェクトのコレクションが含まれて居る DataViewSettingCollection には DataSet の各テーブルに対応する DataViewSetting オブジェクトが 1 つ宛含まれて居る 参照テーブルの既定の ApplyDefaultSort Sort RowFilter RowStateFilter の各プロパティを設定するには DataViewSetting を使用する 名前や序数参照に依って 又は 参照を其の特定のテーブルオブジェクトに渡す事に依って 特定のテーブルの DataViewSetting を参照出来る DataViewManager の DataViewSetting オブジェクトのコレクションにアクセスするには DataViewSettings プロパティを使用する -67-
68 DataSet に SQL Server Northwind データベースの Customers Orders Order Details の各テーブルを格納し テーブル間のリレーションシップを作成し DataViewManager を使用して既定の DataView 設定を設定し DataGrid を DataViewManager に連結するコード例を次に示す 此の例では DataSet の総てのテーブルを対象とした既定の DataView 設定が設定される 此の設定では テーブルの主キーに依ってテーブルの内容が並べ替えられ (ApplyDefaultSort = true) 次に Customers テーブルの並替順序が CompanyName に依る並替順序に変更される ' Assumes connection is a valid SqlConnection to Northwind. ' Create a Connection, DataAdapters, and a DataSet. Dim custda As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CustomerID, CompanyName FROM Customers", connection) Dim orderda As SqlDataAdapter = New SqlDataAdapter( _ "SELECT OrderID, CustomerID FROM Orders", connection) Dim orddetda As SqlDataAdapter = New SqlDataAdapter( _ "SELECT OrderID, ProductID, Quantity FROM [Order Details]", connection) Dim custds As DataSet = New DataSet( ) ' Open the Connection. connection.open( ) ' Fill the DataSet with schema information and data. custda.missingschemaaction = MissingSchemaAction.AddWithKey orderda.missingschemaaction = MissingSchemaAction.AddWithKey orddetda.missingschemaaction = MissingSchemaAction.AddWithKey custda.fill(custds, "Customers") orderda.fill(custds, "Orders") orddetda.fill(custds, "OrderDetails") ' Close the Connection. connection.close( ) ' Create relationships. custds.relations.add("customerorders", _ custds.tables("customers").columns("customerid"), _ custds.tables("orders").columns("customerid")) custds.relations.add("orderdetails", _ custds.tables("orders").columns("orderid"), _ custds.tables("orderdetails").columns("orderid")) ' Create default DataView settings. Dim viewmanager As DataViewManager = New DataViewManager(custDS) Dim viewsetting As DataViewSetting For Each viewsetting In viewmanager.dataviewsettings viewsetting.applydefaultsort = True Next viewmanager.dataviewsettings("customers").sort = "CompanyName" ' Bind to a DataGrid. -68-
69 Dim grid As System.Windows.Forms.DataGrid = New System.Windows.Forms.DataGrid( ) grid.setdatabinding(viewmanager, "Customers") // Assumes connection is a valid SqlConnection to Northwind. // Create a Connection, DataAdapters, and a DataSet. SqlDataAdapter custda = new SqlDataAdapter( "SELECT CustomerID, CompanyName FROM Customers", connection); SqlDataAdapter orderda = new SqlDataAdapter( "SELECT OrderID, CustomerID FROM Orders", connection); SqlDataAdapter orddetda = new SqlDataAdapter( "SELECT OrderID, ProductID, Quantity FROM [Order Details]", connection); DataSet custds = new DataSet( ); // Open the Connection. connection.open( ); // Fill the DataSet with schema information and data. custda.missingschemaaction = MissingSchemaAction.AddWithKey; orderda.missingschemaaction = MissingSchemaAction.AddWithKey; orddetda.missingschemaaction = MissingSchemaAction.AddWithKey; custda.fill(custds, "Customers"); orderda.fill(custds, "Orders"); orddetda.fill(custds, "OrderDetails"); // Close the Connection. connection.close( ); // Create relationships. custds.relations.add("customerorders", custds.tables["customers"].columns["customerid"], custds.tables["orders"].columns["customerid"]); custds.relations.add("orderdetails", custds.tables["orders"].columns["orderid"], custds.tables["orderdetails"].columns["orderid"]); // Create default DataView settings. DataViewManager viewmanager = new DataViewManager(custDS); foreach (DataViewSetting viewsetting in viewmanager.dataviewsettings) viewsetting.applydefaultsort = true; viewmanager.dataviewsettings["customers"].sort = "CompanyName"; // Bind to a DataGrid. System.Windows.Forms.DataGrid grid = new System.Windows.Forms.DataGrid( ); grid.setdatabinding(viewmanager, "Customers"); -69-
データアダプタ詳細
データベース DataAdapter クラス DataAdapter クラスの概要 DataSet へのデータの格納やデータソースの更新に使用される一連の SQL コマンドとデータベース接続を表す DataAdapter は DataSet とデータソースとの間でデータの取得と保存を行う為の ブリッジの役割を果たす DataAdapter は 此のブリッジを提供する為に DataSet 内のデータをデータソース内のデータと一致する様に変更する
ADO.NETのアーキテクチャ
データベース ADO.NET のアーキテクチャ 従来のデータ処理は 主に接続をベースとした 2 層モデルに基づいて居た 最近のデータ処理では 多階層アーキテクチャが多用される様に成った為 プログラマは 非接続型アプローチへと切り替えて アプリケーションに より優れたスケーラビリティを提供して居る ADO.NET のコンポーネント ADO.NET には データへのアクセスとデータの操作に使用出来るコンポーネントが
データアダプタ概要
データベース TableAdapter クエリを実行する方法 TableAdapter クエリは アプリケーションがデータベースに対して実行出来る SQL ステートメントやストアドプロシージャで TableAdapter で型指定されたメソッドと仕て公開される TableAdapter クエリは 所有るオブジェクトのメソッドと同様に 関連付けられたメソッドを呼び出す事に依り実行出来る TableAdapter
データアダプタ概要
データベース データアダプタ データアダプタの概要 データアダプタは ADO.NET マネージプロバイダの重要な部分で有り データソースとデータセットの間の通信に使用されるオブジェクトのセットで有る マネージプロバイダには アダプタの他に接続オブジェクト データリーダーオブジェクト 及び コマンドオブジェクトが含まれる アダプタは データソースとデータセットの間でデータを交換する為に使用される 多くのアプリケーションでは
データベースプログラミング
データセットとデータテーブル データセット (DataSet) とは何かに付いて 簡単に説明する データセットとは 典型的な.NET の Windows データベースアプリケーションでは データセットを通じてアプリケーションからデータベースにアクセスする データセットとは 簡単に謂うと データベースから取得したレコードをメモリ上に持つ為の入れ物で有る 例えば データベースからレコードを取得し 其れをグリッドコントロールに表示する様な
VB実用⑤ アクセス操作Ⅲ
VB でアクセス操作 Ⅲ VB 2005 5 プログラムの概要 前回に引き続き 此処では コードに依るデータベースの操作方法を学ぶ コネクションオブジェクトを用いてデータベースと接続し 表形式でデータを表示するデータグリッドビューコントロールにレコードデータを自動的に表示する手法を学ぶ 既に学んだ様にコントロールを連結する事に依り コードレスでデータベース操作が可能で有るが 此処では 着目して居る行
TableAdapterクラス
テーブルアダプタ TableAdapter の概要 TableAdapter を使用すると アプリケーションとデータベース間で通信する事が出来る様に成る 具体的には TableAdapter は データベースに接続し クエリやストアドプロシージャを実行し 返されたデータが格納された新しいデータテーブルを返すか 返されたデータを既存の DataTable に格納する TableAdapter は 更新されたデータをアプリケーションからデータベースに送り返す場合にも使用する
VB.NET解説
Visual Basic.NET データベース編 目次 ADO.NET の概要... 2 ADO.NET と ADO... 2 ADO.NET の仕組み... 4 ADO.NET の特徴... 7 データアクセスの基本... 8 Windows アプリケーションの開発手順... 8 データ接続の作成... 9 データアダプタとコネクションの作成...10 データセットの作成...14 データアクセスの利用...21
VB実用③ アクセス操作Ⅰ
VB でアクセス操作 Ⅰ VB 2005 3 プログラムの概要 此処では コントロールを使用しないで コードに依るデータベースへの接続とデータの取得の方法を学ぶ コントロールに依るデータベース接続は 簡単にデータベースを操作する事が出来ると謂う利点が有り 小規模な運用で有れば 充分な能力を発揮する 併し 中規模 大規模に成り 複雑な操作を必要とする様に成れば 力不足に成る可能性が高く成る 然う成れば
ICONファイルフォーマット
グラフィックス 画像フォーマットエンコーダパラメータ 様々なフォーマットで画像を保存 Bitmap クラスを用いる事でビットマップ JPEG GIF PNG 等様々なフォーマットの画像を読み込み操作する事が出来る 更に Bitmap クラスや Graphics コンテナを用いて描画処理等を施したイメージをファイルに保存する事も出来る 此の時 読み込めるフォーマット同様に保存するフォーマットを選択する事が出来る
ファイル操作-バイナリファイル
ファイル操作 バイナリ ファイルを読み書きする バイナリファイル ( 即ちテキストファイル以外のファイル ) を読み書きするには FileStream クラス (System.IO 名前空間 ) を利用する FileStream クラスはファイル用のストリームをサポートするクラスで有り Stream クラス (System.IO 名前空間 ) の派生クラスの 1 つで有る 基本的には コンストラクタで指定したファイルのストリームに対して
Visual Basic 資料 電脳梁山泊烏賊塾 コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値
コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値 ( 此処では 10) を代入する丈でなく 2 の配列変数の宣言の様に ブレース { } の中にカンマ区切りで初期値のリストを記述し 配列の各要素に初期値を代入出来る様に成った
VB実用④ アクセス操作Ⅱ
VB でアクセス操作 Ⅱ VB 2005 4 プログラムの概要 前回に引き続き 此処では コードに依るデータベースの操作方法を学ぶ コネクションオブジェクトを用いてデータベースと接続し 表形式でデータを表示するデータグリッドビューコントロールにレコードデータを自動的に表示する手法を学ぶ 既に学んだ様にコントロールを連結する事に依り コードレスでデータベース操作が可能で有るが 此処では 着目して居る行
ハッシュテーブル
ハッシュテーブル ハッシュテーブル ( 連想配列 ) を使う ハッシュテーブルとは キー (key) と値 (value) のペアを保持して居るコレクションで有る 通常の配列がインデックス番号に依り各値 ( 各要素 ) にアクセス出来るのに比べて ハッシュテーブルでは インデックス番号の代わりにキーを用いて 其の各値にアクセスする事が出来る キーと 其のキーから連想される ( 対応付けられて居る )
ファイル操作
ファイル操作 TextFieldParser オブジェクト ストリームの読込と書込 Microsoft.VisualBasic.FileIO 名前空間の TextFieldParser オブジェクトは 構造化テキストファイルの解析に使用するメソッドとプロパティを備えたオブジェクトで有る テキストファイルを TextFieldParser で解析するのは テキストファイルを反復処理するのと同じで有り
正規表現応用
正規表現 正規表現を使って文字列が或る形式と一致するか調べる 指定された正規表現のパターンと一致する対象が入力文字列内で見付かるか何うかを調べるには Regex クラスの IsMatch メソッドを使用する 此処では IsMatch メソッドを使った例を幾つか紹介する 猶 正規表現のパターンと一致する個所を探し 見付かれば 其の箇所を抽出する方法は 正規表現を使って文字列を検索し 抽出する で紹介して居る
構造体
構造体 Byte 配列 構造体とコピーする方法 構造体とバイト配列の変換を行うには System.Runtime.InteropServices 名前空間をインポートして置くと便利で有る Imports System.Runtime.InteropServices using System.Runtime.InteropServices; 下記の 3 種類の構造体にバイト配列の値を格納した場合に付いて検証する
intra-mart Accel Platform — TableMaintenance ユーザ操作ガイド 第7版 None
クイック検索検索 目次 Copyright 2012 NTT DATA INTRAMART CORPORATION 1 Top 目次 改訂情報概要レコードの追加 / 更新 / 削除レコードの編集レコードを削除するレコードの一括インポートとエクスポート日本語のキャプション表示 2 改訂情報 変更年月日 変更内容 2012-10-01 初版 2013-10-01 第 2 版下記が追加 変更されました 対応するフィールドの型
mySQLの利用
MySQL の利用 インストール インストール時に特に注意点は無い 本稿記述時のバージョンは 6.5.4 で有る (2017 年 11 月現在では 6.10.4 で https://dev.mysql.com/downloads/connector/net/6.10.html よりダウンロード出来る ) 参照設定 インストールが終了すれば Visual Studio で参照の設定を行う 参照の設定画面で
VB.NET解説
Visual Basic.NET 印刷編 目次 印刷の概要... 2 印刷の流れ... 2 標準の Windows フォーム印刷ジョブの作成... 3 実行時に於ける Windows フォーム印刷オプションの変更... 3 Windows フォームに於ける接続されたプリンタの選択... 4 Windows フォームでのグラフィックスの印刷... 5 Windows フォームでのテキストの印刷...
1 SQL Server SQL Oracle SQL SQL* Plus PL/SQL 2 SQL Server SQL Server SQL Oracle SQL SQL*Plus SQL Server GUI 1-1 osql 1-1 Transact- SQL SELECTFROM 058
1 SQL Server SQL Oracle SQL SQL* Plus PL/SQL 2 SQL Server SQL Server SQL Oracle SQL SQL*Plus SQL Server GUI 1-1 osql 1-1 Transact- SQL SELECTFROM 058 2 Excel 1 SQL 1 SQL Server sp_executesql Oracle SQL
プロセス間通信
プロセス間通信 プロセス間通信 (SendMessage) プロセス間通信とは 同一コンピューター上で起動して居るアプリケーション間でデータを受け渡し度い事は時々有る Framework には リモート処理 と謂う方法でデータの受け渡しを行なう方法が有る 此処では 此の方法では無く 従来の方法の API を使用したプロセス間通信を紹介する 此の方法は 送信側は API の SendMessage で送り
Microsoft認定資格問題集(70-483_demo)
Microsoft 認定資格問題集 受験番号 : 70-483 受験名 : C# でのプログラミング言語 : 日本語問題数 :179 問 テストバリュー (TESTVALUE) はこの日本語版問題集の著作権を所有します 問題集の他人への展開 譲渡 転売 複製 転載等の無断行為は法律上で禁止されています 違反が発覚した場合 法的措置を取らせて頂きますので 予めご了承ください 問題 1 Orderオブジェクトのコレクションがあります
intra-mart Accel Platform — TableMaintenance ユーザ操作ガイド 第8版
Copyright 2012 NTT DATA INTRAMART CORPORATION 1 Top 目次 改訂情報概要レコードの追加 / 更新 / 削除レコードの編集レコードを削除するレコードの一括インポートとエクスポート日本語のキャプション表示 2 改訂情報 変更年月日 変更内容 2012-10-01 初版 2013-10-01 第 2 版下記が追加 変更されました 対応するフィールドの型 が追加されました
プログラミング基礎I(再)
山元進 クラスとは クラスの宣言 オブジェクトの作成 クラスのメンバー フィールド 変数 配列 メソッド メソッドとは メソッドの引数 戻り値 変数の型を拡張したもの 例えば車のデータベース 車のメーカー 車種 登録番号などのデータ データベースの操作 ( 新規データのボタンなど ) プログラムで使う部品の仕様書 そのクラスのオブジェクトを作ると初めて部品になる 継承 などの仕組みにより カスタマイズが安全
ADOとADO.NET
ADO と ADO.NET Visual Basic.NET では 従来の ADO を従来の方法で使用する事も出来るが 通常 データベースにアクセスする為に ADO.NET を使用する 此処では Windows 上で動作するアプリケーションの開発に必要な知識を中心に ADO と ADO.NET の差異を説明する Visual Basic 6.0 では データベースにアクセスする為に ADO(ActiveX
ListViewコントロール
ListView コントロール ListView コントロールへ項目を追加 本稿では.NET Framework の標準コントロールで有る ListView コントロール (System.Windows.Forms 名前空間 ) を活用する為に ListView コントロールにデータを追加する方法を紹介する ListView コントロールは データ項目をアイコン表示や詳細表示等に依り一覧表示する為の物で
DAOの利用
DAO VB2005 で DAO を使用して Excel のデータを取得 Visual Basic 6.0 Dim DB As DAO.Database Dim RS As DAO.Recordset Dim xlfilename As String Dim xlsheetname As String xlfilename = Form1.StatusBar1.Panels(12) & Dir(Form1.StatusBar1.Panels(12)
データベースの更新の実行
データベース データベースの更新の実行 概要 解らない事を信じて居るから 苦しむのさ 迷信は駄目だ スティービーワンダー スティービーワンダーは 勿論データベースの更新の事を謂って居た訳ではないだろうが 此の言葉は確かに此のテーマにも当て嵌る ADO.NET のデータベース更新機能は非常に強力だが.NET がベータ版だった頃に内外のニュースグループに寄せられた疑問や セミナー等で出された質問からすると
目次 更新履歴... 1 はじめに... 3 レコードセット?... 3 準備... 5 SQL でデータを取得する... 6 データのループ処理... 7 列の値を取得する... 7 対象行を変更する (MoveFirst, MoveNext, MovePrevious, MoveLast)...
レコードセット (ADODB.Recordset) の使い方 作成日 : 2018/02/05 作成者 : 西村 更新履歴 更新日 更新概要 作業者 2018/02/05 新規作成 西村 1 目次 更新履歴... 1 はじめに... 3 レコードセット?... 3 準備... 5 SQL でデータを取得する... 6 データのループ処理... 7 列の値を取得する... 7 対象行を変更する (MoveFirst,
VB実用Ⅲ⑩ フリーデータベースⅡ
MySQL の利用 MySQL の ODBC(MyODBC) テキストでは MySQL Connector/ODBC(mysql-connector-odbc-3.51.14-win32.msi) をインストールした場合に付いて解説して居るが 此処では MyODBC(MyODBC-3.51.10-x86-win-32bit.msi) をインストールし myodbc-3.51.06-conv_ujis.zip
グラフィックス
グラフィックス PictureBox の Image プロパティに関する良く有る勘違い PictureBox に画像を表示する方法と仕て PictureBox の Image プロパティを使う方法と Graphics の DrawImage メソッドを使う方法が有るが 此の 2 つの方法を混同し 正しく理解して居ない事が多い様で有る 例えば 下記に列挙する様な状況が 此れに該当する 1.PictureBox
VB実用① データベースⅠ
VB でデータベース Ⅰ VB 2005 1 プログラムの概要 データベースプログラムを手軽に作成する方法と仕ては Access のフォーム機能を用いる事が 先ず考えられる ウィザードも充実して居り 操作を覚えれば簡単に作成する事が出来る 其れでは VB でデータベースプログラムを作るメリットは何かと謂えば先ず Access のフォーム機能に比べ コントロールが充実して居り より自由なデザインが可能と謂う事と
Userコントロール
User コントロール 初めてのユーザーコントロールの作成 作成したクラスは他のプログラムで再利用出来る為 同じコードを何度も繰り返し作成する必要が無い コントロールも 複数のプロジェクトで再利用出来るクラスで有る 同じユーザーインターフェイスを何度も繰り返してデザインすると謂う経験は 恐らく誰でも有る 例えば 姓と名を入力する為の TextBox コントロールを追加した後で 両方を組み合わせてフルネームを作成するコードを追加する等の作業で有る
VB6互換のファイルの処理
Visual Basic のランタイム関数を使用したファイルアクセス FileOpen 関数 ファイルを開いて入出力を行う FileOpen(FileNumber, FileName, Mode[, Access[, Share[, RecorLength]]]) 引数 FileNumber は必ず指定する 有効なファイル番号を指定する FreeFile 関数を使用して 使用可能な次のファイル番号を取得する事が出来る
PowerPoint Presentation
UiPath 女性ユーザー コミュニティ第 1 回 Meetup 2018.9.12 (WED) 女性ユーザーコミュニティ概要 目的 : まだまだ男性と比べると数が少ない UiPath を使ってる女性ユーザーに対し 勉強 意見交換ができる場を提供し 女性ユーザーをさらに増やします 対象 : 仕事で UiPath を使っている これから使う予定の女性の方 コミュニティ内容 : 勉強会 交流会の実施 デベロッパーコミュニティと何が違うの?
intra-mart Accel Platform — IM-Repository拡張プログラミングガイド 初版
Copyright 2018 NTT DATA INTRAMART CORPORATION 1 Top 目次 1. 改訂情報 2. はじめに 2.1. 本書の目的 2.2. 対象読者 2.3. サンプルコードについて 2.4. 本書の構成 3. 辞書項目 API 3.1. 最新バージョン 3.1.1. 最新バージョンの辞書を取得する 3.2. 辞書項目 3.2.1. 辞書項目を取得する 3.2.2.
NotifyIconコントロール
NotifyIcon コントロール システムトレイ ( タスクトレイ ) にアイコンを表示する.NET Framework 2.0 以降の場合は 後述の 2 を観て欲しい Outlook や MSN Messenger 等の様に Windows アプリケーションではシステムトレイ ( タスクトレイ ステータス領域等とも呼ばれる ) にアイコンを表示して アプリケーションの状態を示したり アプリケーションのフォームを表示したりする為のショートカットとして利用する事が出来る.NET
内容 Visual Studio サーバーエクスプローラで学ぶ SQL とデータベース操作... 1 サーバーエクスプローラ... 4 データ接続... 4 データベース操作のサブメニューコンテキスト... 5 データベースのプロパティ... 6 SQL Server... 6 Microsoft
Visual Studio サーバーエクスプローラで学ぶ SQL とデータベース操作 Access 2007 と SQL Server Express を使用 SQL 文は SQL Server 主体で解説 Access 版ノースウィンドウデータベースを使用 DBMS プログラム サーバーエクスプローラ SQL 文 実行結果 データベース エンジン データベース SQL 文とは 1 度のコマンドで必要なデータを効率よく取得するための技術といえます
.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~
.NET プログラマー早期育成ドリル VB 編 付録文法早見表 本資料は UUM01W:.NET プログラマー早期育成ドリル VB 編コードリーディング もしくは UUM02W:.NET プログラマー早期育成ドリル VB 編コードライティング を ご購入頂いた方にのみ提供される資料です 資料内容の転載はご遠慮下さい VB プログラミング文法早見表 < 基本文法 > 名前空間の定義 Namespace
PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 関数とメソッド 関数とメソッド Python には関数 (function) とメソッド (method) が有る モジュール内に def で定義されて居る物が関数 クラス内に def で定義されて居る物がメソッドに成る ( 正確にはクラスが
PYTHON 入門 関数とメソッド 関数とメソッド Python には関数 (function) とメソッド (method) が有る モジュール内に def で定義されて居る物が関数 クラス内に def で定義されて居る物がメソッドに成る ( 正確にはクラスがインスタンス化されてからメソッドに成る ) # 関数 def test_func(): print('call test_func') #
Seasar.NET入門
2007 Spring Seasar.NET 入門 2007.5.27 Seasar.NET 杉本和也 2007 Spring Copyright 2004-2007 The Seasar Foundation and the others. All rights reserved. 1 杉本和也と申します 高知県の株式会社アイビスに勤務しています プログラミング歴 6 年 オープンソース歴 2 年
Exam : J Title : Querying Microsoft SQL Server 2012 Version : DEMO 1 / 10
PASSEXAM http://www.passexam.jp Exam : 70-461J Title : Querying Microsoft SQL Server 2012 Version : DEMO 1 / 10 1. あなたが ContosoDb 付きの Microsoft SQL Server 2012 のデータベースを管理します 展示に示すように テーブルが定義されています ( 図表ボタンをクリックします
ファイル監視
ファイル操作 ファイルやディレクトリの監視 FileSystemWatcher クラス.NET Framework のクラスライブラリには ファイルやディレクトリの作成 変更 削除を監視する為の FileSystemWatcher クラスが System.IO 名前空間に用意されて居る ( 但し Windows 98/Me では利用出来ない ) 此れを利用すると 特定のディレクトリにファイルが作成された
NetCOBOL for .NET 応用編
5.1 NetCOBOL for.net 5.2 ADO.NET 5.3 SQL 5.4 READ/WRITE 5.5 5.6 SQL CLR 125 NetCOBOL for.netread/write SQL.NET FrameworkADO.NET 3 Windows NetCOBOL (Oracle Pro*COBOL) READ/WRITE Btrieve Pervasive PowerRDBconnector
VB 資料 電脳梁山泊烏賊塾 音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るの
音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るので 此れを利用して音声認識を行うサンプルを紹介する 下記の様な Windows フォームアプリケーションを作成する エディタを起動すると
スライド 1
XML with SQLServer ~let's take fun when you can do it~ Presented by 夏椰 ( 今川美保 ) Agenda( その 1) XML XML XSLT XPath XML Schema XQuery Agenda( その 2) SQLServer における XML XML 型 XML Schema XQuery & XPath チェック制約
Oracle Lite Tutorial
GrapeCity -.NET with GrapeCity - FlexGrid Creation Date: Nov. 30, 2005 Last Update: Nov. 30, 2005 Version: 1.0 Document Control Internal Use Only Author Hiroshi Ota Change Logs Date Author Version Change
ITdumpsFree Get free valid exam dumps and pass your exam test with confidence
ITdumpsFree http://www.itdumpsfree.com Get free valid exam dumps and pass your exam test with confidence Exam : C9530-001J Title : IBM Integration Bus v10.0, Solution Development Vendor : IBM Version :
Microsoft Word - JDBC検証 docx
ASTERIA WARP 4.9/1610 でのサードパーティ製 JDBC ドライバ動作検証報告書 2016 年 12 インフォテリア株式会社 本書は著作権法により保護されています インフォテリア株式会社による事前の許可無く 本書のいかなる部分も無断転載 複製 複写を禁じます 本書の内容は予告無しに変更する事があります Infoteria インフォテリア ASTERIA WARP はインフォテリア株式会社の商標です
VB実用⑦ エクセル操作Ⅰ
VB でエクセル操作 Ⅰ VB 2005 7 プログラムの概要 事務処理に於いて Microsoft 社のスプレッドシートソフトで有るエクセルは データベースソフトで有るアクセスと共に 業界標準 (De Facto Standard) で有ると謂う事が出来る 此処では 其のエクセルを Visual Basic から操作する方法を 重点的に学ぶ 今回は Visual Basic でエクセルを利用する基本と成るオブジェクト生成と
XMLプログラミング(ADO編)
XML プログラミング ADO 2.5 と XML ADO 2.5 と XML ADO 2.5 を利用すれば 粗所有るデータソースからのデータの読み取りや ADO レコードセット ( メモリ上にデータを持つ仮想テーブルの様な物 ) へのデータの配置 XML へのデータ変換が可能に成る XML に変換したデータをデータストリームに配置すれば ファイルや ADO ASP Response オブジェクト
PowerPoint Presentation
Webデザイン特別プログラムデータベース実習編 3 MySQL 演習, phpmyadmin 静岡理工科大学総合情報学部幸谷智紀 http://na-inet.jp/ RDB の基礎の基礎 RDB(Relational DataBase) はデータを集合として扱う データの取り扱いはテーブル (= 集合 ) の演算 ( 和集合, 積集合 ) と同じ データベースには複数のテーブルを作ることができる
データベースアクセス
データベースアクセスコンポーネント 1. 概要 データベースアクセスコンポーネントとは SQL データベースにアクセスして SQL 文を実行することによりデータベース検索を行う機能を提供するコンポーネントです また データベースアクセスコンポーネントでは データベースの構成情報 接続情報 エラー情報等を取得することも可能です データベースアクセスコンポーネントは アプリケーションビルダーのメニューから以下のように選びます
JavaプログラミングⅠ
Java プログラミング Ⅰ 12 回目クラス 今日の講義で学ぶ内容 クラスとは クラスの宣言と利用 クラスの応用 クラス クラスとは 異なる複数の型の変数を内部にもつ型です 直観的に表現すると int 型や double 型は 1 1 つの値を管理できます int 型の変数 配列型は 2 5 8 6 3 7 同じ型の複数の変数を管理できます 配列型の変数 ( 配列変数 ) クラスは double
Javaプログラムの実行手順
戻り値のあるメソッド メソッドには 処理に使用する値を引数として渡すことができました 呼び出し 側からメソッドに値を渡すだけでなく 逆にメソッドで処理を行った結果の値を 呼び出し側で受け取ることもできます メソッドから戻してもらう値のことを もどりち戻り値といいます ( 図 5-4) 図 5-4. 戻り値を返すメソッドのイメージ 戻り値を受け取ることによって ある計算を行った結果や 処理に成功したか失
第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ
第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイルの作成方法 コンパイル方法について説明します IDL ファイルの作成にあたっては INTERSTAGE
データベースⅠ
データベース操作プログラム Ⅰ VB 2005 8 プログラムの概要 データベースプログラムを手軽に作成する方法としては Access のフォーム機能を用いる事が 先ず考えられます ウィザードも充実しており 操作を覚えれば簡単に作成する事が出来ます 其れでは VB でデータベースプログラムを作るメリットは何んでしょうか 1 つは Access のフォーム機能に比べ コントロールが充実している事 より自由なデザインが可能です
- i - org.t_engine.tenet.core.coreerrormessageexception org.t_engine.tenet.core Class CoreErrorMessageException java.lang.object +-java.lang.throwable +-java.lang.exception +-org.t_engine.tenet.core.coreexception
Visual Basic Oracle Database 11 Release 1
Visual Basic 2008 + Oracle Database 11 Release 1 2008.01.26 初音玲 Part.1 Oracle Database 製品について Oracleクライアントコンポーネントについて ODP.NETについて OracleConnectionクラスについて Oracle Database 製品について Oracleクライアントコンポーネントについて
intra-mart Accel Platform — IM-共通マスタ スマートフォン拡張プログラミングガイド 初版
Copyright 2012 NTT DATA INTRAMART CORPORATION 1 Top 目次 1. 改訂情報 2. IM- 共通マスタの拡張について 2.1. 前提となる知識 2.1.1. Plugin Manager 2.2. 表記について 3. 汎用検索画面の拡張 3.1. 動作の概要 3.1.1. 汎用検索画面タブの動作概要 3.2. 実装の詳細 3.2.1. 汎用検索画面タブの実装
64bit環境で32bitコンポーネントの利用
64bit 環境 64bit 環境で 32bit コンポーネントの利用 Windows 7 や 8 の出現で 愈々 64bit 環境も普及し始めて来た 64bit 環境に於いては 64bit 用に最適化された 64bit コンポーネントを使用するのが本筋で有ろうが 64bit 環境に於いても 32bit コンポーネントを使用し度い場合が有る 過去の遺物 ( レガシ ) と仕て切り捨てるのではなく 良い物は良い物と仕て有効利用すると謂う観点から
Microsoft PowerPoint - db03-5.ppt
データベース言語 SQL リレーショナルデータモデルにおけるデータ操作言語 : リレーショナル代数 少なくともリレーショナル代数と同等のデータ検索能力をもつときリレーショナル完備という. リレーショナル代数はユーザフレンドリではない. 自然な英文による質問の表現が必要になる. リレーショナルデータベース言語 SQL 英文による簡単な構文 リレーショナル代数でできない, 合計, 平均, 最大などの計算機能の組み込み.
Microsoft Excel操作
Microsoft Excel 操作 Excel ファイルにアクセス リフレクションを利用したレイトバインディングで Excel ファイルを操作 Visual Basic なら CreatObject 関数を使用して 暗黙の遅延バインディングを利用する事に依り 簡単にに実現出来る Excel の操作も C# で実現するには 少し面倒臭い事に成る 事前バインディングでも実装する事も出来るが 事前バインディングだと
ウィンドウ操作 応用
Win32API 関数 ウィンドウ操作 ウィンドウ名でトップレベルウィンドウ ( 親を持たないウィンドウ ) のハンドルを取得 メモ帳や電卓等のウィンドウ名でトップレベルウィンドウ ( 親を持たないウィンドウ ) のハンドルを取得する方法を 下記に示す Visual Basic Imports System.Runtime.InteropServices Public Class WindowFromWindowName
Android Layout SDK プログラミング マニュアル
プログラミングマニュアル Version 1.3.0 用 更新履歴 年月日 バージョン 履歴 2014.09.08 1.2.0.0 新規 (Layout Utilities ユーザーズ ガイド ) 2016.08.16 1.3.0.0 モバイル端末用レイアウトで直線部品と矩形部品に対応 モバイル端末用レイアウトファイルを CLFX から XML へ変更 Layout Print Engine から
Microsoft Office操作(EXCEL)
VB から Excel にデータを転送する方法 概要 此の資料では Microsoft Visual Basic アプリケーションから Microsoft Excel にデータを転送する様々な方法に付いて説明する 亦 最適なソリューションの選択に役立つ様に 夫々れの方法の長所と短所に付いても説明する 詳細 Excel ブックにデータを転送するのに最も良く使用されるのは オートメーションと呼ばれる技法で有る
C 資料 電脳梁山泊烏賊塾 ファイルの入出力 C++ のバイナリファイル入出力 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する
ファイルの入出力 C++ のバイナリファイル入出力 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 使用クラス C++ の場合 ファイルの入出力に使用するクラスは ifstream ofstream fstream の 3 種類が有り 頭に i(input)
(OnePoint) ( URL Web Copyright 2005 Microsoft Corporation. All rights reserved. MicrosoftWindowsVisual Basic Visual Studio Microsoft Corporation
Microsoft Microsoft Visual Basic.NET (OnePoint) ( URL Web Copyright 2005 Microsoft Corporation. All rights reserved. MicrosoftWindowsVisual Basic Visual Studio Microsoft Corporation Microsoft Microsoft
Oracle Lite Tutorial
GrapeCity -.NET with GrapeCity - InputMan Creation Date: Nov. 30, 2005 Last Update: Nov. 30, 2005 Version: 1.0 GrapeCity Microsoft Visual Studio.NET VB.NET Oracle Tips InputMan InputMan Oracle.NET Oracle
いまさら聞けないVB2008 ADO.NET超入門
自己紹介 Z80 アセンブラ 6809 アセンブラ F-BASIC N88-BASIC FORTRAN 77 COBOL LISP Turbo Pascal Prolog KABA C 言語 M シリーズ アセンブラ PL/I VB3.0~ PL/SQL T-SQL VB2005/2008 index 接続 データ取得 データ更新 権限 ADO.NET の基本的な構造.NET データプロバイダ Parameter
Java知識テスト問題
Java 知識テスト SDAS プログラマ(Java 編 ) 運営事務局 このテストは J2EE プログラマとしての Java の知識を評価するものです 問題は 30 問, テスト時間は J2EE 知識テストとあわせて 90 分です 問題は全て択一式です 選択肢から 1 つだけ選択してください 資料の閲覧は禁止です テストが終わり次第 答案用紙を提出していただいてかまいません テスト終了後, 本テストの内容を他の方に話さないでください
1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String
目次 1.SqlCtl クラスリファレンス 2 (1)Connect() メソッド 2 (2)DisConnect() メソッド 3 (3)Commit() メソッド 3 (4)Rollback() メソッド 4 2.SqlStm クラスリファレンス 5 (1)Prepare() メソッド 5 (2)Execute() メソッド 6 (3)Release() メソッド 6 (4)Immediate()
PowerPoint Presentation
上級プログラミング 2( 第 5 回 ) 工学部情報工学科 木村昌臣 今日のテーマ データベース入門 データベースシステムの用意の仕方 データベースを作ってみる データベースを使ってみる データベースプログラミング JDBCを使った検索プログラム JDBCを使った更新プログラム データベース入門 今回の説明は Windows 環境を前提としているため Linux など他のプラットフォーム上で作業を行う場合は
第 2 章 PL/SQL の基本記述 この章では PL/SQL プログラムの基本的な記述方法について説明します 1. 宣言部 2. 実行部 3. 例外処理部
はじめに コース概要と目的 Oracle 独自の手続き型言語である PL/SQL について説明します PL/SQL の基本構文 ストアド サブプログラム トリガーの作成方法 またストアド サブプログラムの管理について習得することを目的としています 受講対象者 これから PL/SQL を使用してアプリケーション開発をされる方 前提条件 SQL トレーニング コースを受講された方 もしくは 同等の知識をお持ちの方
MVP for VB が語る C# 入門
MVP for VB が語る C# 入門 2008.08.09 初音玲 自己紹介 Z80 アセンブラ 6809 アセンブラ F-BASIC N88-BASIC FORTRAN 77 COBOL LISP Turbo Pascal Prolog KABA C 言語 M シリーズ アセンブラ PL/I VB3.0~ PL/SQL T-SQL VB2005/2008 index Microsoft Visual
本書は INpMac v2.20(intime 5.2 INplc 3 Windows7/8/8.1に対応 ) の内容を元に記載しています Microsoft Windows Visual Studio は 米国 Microsoft Corporation の米国及びその他の国における登録商標です
ACTIVE TOUCH 拡張部品取扱説明書 - 共有メモリアクセスコンポーネント - 1. はじめに 1 (1) 概要... 1 (2) INpMac のインストール... 1 2. Windows アプリケーションとの連携 2 (1) コントロール ( 部品 ) の登録... 2 (2) データの関連付け... 3 3. INtime アプリケーションとの連携 4 (1) 部品 ( コンポーネント
