注
DataSet クラスと関連クラスは、アプリケーションがデータベースから切断されている間にアプリケーションがメモリ内のデータを操作できるようにする、2000 年代初頭のレガシ .NET Framework テクノロジです。 このテクノロジは、ユーザーがデータを変更し、変更をデータベースに保持できるアプリに特に役立ちます。 データセットは実証済みの成功したテクノロジですが、新しい .NET アプリケーションには Entity Framework Core を使用することをお勧めします。 Entity Framework は、オブジェクト モデルとして表形式データを操作するより自然な方法を提供し、よりシンプルなプログラミング インターフェイスを備えています。
データの検証は、データ オブジェクトに入力されている値がデータセットのスキーマ内の制約に準拠していることを確認するプロセスです。 検証プロセスでは、これらの値がアプリケーションに対して確立された規則に従っていることも確認されます。 基になるデータベースに更新を送信する前に、データを検証することをお勧めします。 これにより、エラーが減り、アプリケーションとデータベース間のラウンド トリップの可能性も減ります。
データセットに書き込まれているデータが有効であることを確認するには、データセット自体に検証チェックを作成します。 データセットは、更新の実行方法に関係なく、フォーム内のコントロール、コンポーネント内、またはその他の方法で直接データをチェックできます。 データセットは (データベース バックエンドとは異なり) アプリケーションの一部であるため、アプリケーション固有の検証を構築するための論理的な場所です。
アプリケーションに検証を追加する最適な場所は、データセットの部分クラス ファイルにあります。 Visual Basic または Visual C# でデータセット デザイナー を開き、検証を作成する列またはテーブルをダブルクリックします。 このアクションにより、コード ファイルが開き、 ColumnChanging または RowChanging イベント ハンドラーを作成できます。
データを検証する
データセット内の検証は、次の方法で実行されます。
変更中に個々のデータ列の値をチェックできる独自のアプリケーション固有の検証を作成します。 詳細については、「 方法: 列の変更中にデータを検証する」を参照してください。
アプリケーション固有の検証を独自に作成して、データ行全体が変更される際に、データの値をチェックできるようにする。 詳細については、「 方法: 行の変更中にデータを検証する」を参照してください。
データセットの実際のスキーマ定義の一部として、キーや一意の制約などを作成します。
MaxLength、AllowDBNull、Uniqueなど、DataColumn オブジェクトのプロパティを設定します。
レコードで変更が発生すると、 DataTable オブジェクトによっていくつかのイベントが発生します。
- ColumnChangingイベントとColumnChangedイベントは、各列の変更中および変更後に発生します。 ColumnChanging イベントは、特定の列の変更を検証する場合に便利です。 提案された変更に関する情報は、イベントと共に引数として渡されます。
- RowChangingイベントとRowChangedイベントは、行の変更中および変更後に発生します。 RowChanging イベントはより一般的です。 これは、行のどこかで変更が行われていることを示しますが、どの列が変更されたかはわかりません。
既定では、列に対する各変更によって 4 つのイベントが発生します。 1 つ目は、変更される特定の列の ColumnChanging イベントと ColumnChanged イベントです。 次に、 RowChanging イベントと RowChanged イベントです。 行に対して複数の変更が行われている場合は、変更ごとにイベントが発生します。
注
データ行の BeginEdit メソッドは、個々の列が変更された後、 RowChanging イベントと RowChanged イベントをオフにします。 その場合、RowChangingイベントとRowChanged イベントが 1 回だけ発生したときに、EndEdit メソッドが呼び出されるまで、イベントは発生しません。 詳細については、「データセットの 入力中に制約を無効にする」を参照してください。
選択するイベントは、検証の粒度によって異なります。 列が変更されたときにすぐにエラーをキャッチすることが重要な場合は、 ColumnChanging イベントを使用して検証をビルドします。 それ以外の場合は、 RowChanging イベントを使用します。その結果、一度に複数のエラーがキャッチされる可能性があります。 さらに、ある列の値が別の列の内容に基づいて検証されるようにデータが構造化されている場合は、 RowChanging イベント中に検証を実行します。
レコードが更新されると、 DataTable オブジェクトは、変更の発生および変更後に応答できるイベントを発生させます。
アプリケーションで型指定されたデータセットを使用する場合は、厳密に型指定されたイベント ハンドラーを作成できます。 これにより、ハンドラーを作成できる 4 つの型指定されたイベント ( dataTableNameRowChanging
、 dataTableNameRowChanged
、 dataTableNameRowDeleting
、 dataTableNameRowDeleted
) が追加されます。 これらの型指定されたイベント ハンドラーは、コードの記述と読み取りを容易にするテーブルの列名を含む引数を渡します。
データ更新イベント
出来事 | 説明 |
---|---|
ColumnChanging | 列の値が変更されています。 イベントは、提案された新しい値と共に行と列をユーザーに渡します。 |
ColumnChanged | 列の値が変更されました。 イベントは、提案された値と共に行と列をユーザーに渡します。 |
RowChanging | DataRow オブジェクトに加えられた変更は、データセットにコミットされようとしています。 BeginEdit メソッドを呼び出していない場合は、ColumnChanging イベントが発生した直後に、列に対する変更ごとにRowChanging イベントが発生します。 変更を行う前に BeginEdit を呼び出した場合、 RowChanging イベントは、 EndEdit メソッドを呼び出したときにのみ発生します。 イベントは、実行されているアクションの種類 (変更、挿入など) を示す値と共に行を渡します。 |
RowChanged | 行が変更されました。 イベントは、実行されているアクションの種類 (変更、挿入など) を示す値と共に行を渡します。 |
RowDeleting | 行が削除されています。 このイベントでは、行と共に、実行されようとしているアクションの種類 (削除) を示す値が渡されます。 |
RowDeleted | 行が削除されました。 イベントは、実行中のアクションの種類(削除)を示す値と共に、行をあなたに渡します。 |
ColumnChanging、RowChanging、およびRowDeletingイベントは、更新プロセス中に発生します。 これらのイベントを使用して、データを検証したり、他の種類の処理を実行したりできます。 これらのイベント中に更新プログラムが処理中であるため、例外をスローすることで取り消すことができます。これにより、更新が完了するのを防ぐことができます。
ColumnChanged、RowChanged、およびRowDeletedイベントは、更新が正常に完了したときに発生する通知イベントです。 これらのイベントは、正常な更新に基づいてさらにアクションを実行する場合に便利です。
列の変更中にデータを検証する
注
データセット デザイナーは、検証ロジックをデータセットに追加できる部分クラスを作成します。 デザイナーによって生成されたデータセットは、部分クラス内のコードを削除または変更しません。
ColumnChanging イベントに応答することで、データ列の値が変更されたときにデータを検証できます。 このイベントが発生すると、現在の列に対して提案されている値を含むイベント引数 (ProposedValue) が渡されます。 e.ProposedValue
の内容に基づいて、次のことができます。
何も行うことで、提案された値を受け入れます。
列変更イベント ハンドラー内から列エラー (SetColumnError) を設定して、提案された値を拒否します。
必要に応じて、 ErrorProvider コントロールを使用して、ユーザーにエラー メッセージを表示します。 詳細については、「ErrorProvider コンポーネント」を参照してください。
検証は、 RowChanging イベント中に実行することもできます。
行の変更中にデータを検証する
検証する各列に、アプリケーションの要件を満たすデータが含まれていることを確認するコードを記述できます。 これを行うには、提案された値が許容できない場合にエラーが含まれていることを示すように列を設定します。 次の例では、 Quantity
列が 0 以下の場合に列エラーを設定します。 行を変更するイベント ハンドラーは、次の例のようになります。
行が変更されたときにデータを検証するには (Visual Basic)
データセット デザイナーでデータセットを開きます。 詳細については、「 チュートリアル: データセット デザイナーでのデータセットの作成」を参照してください。
検証するテーブルのタイトル バーをダブルクリックします。 このアクションにより、データセットの部分クラス ファイルにDataTableのRowChanging イベント ハンドラーが自動的に作成されます。
ヒント
テーブル名の左側をダブルクリックして、行を変更するイベント ハンドラーを作成します。 テーブル名をダブルクリックすると、編集できます。
Private Sub Order_DetailsDataTable_Order_DetailsRowChanging( ByVal sender As System.Object, ByVal e As Order_DetailsRowChangeEvent ) Handles Me.Order_DetailsRowChanging If CType(e.Row.Quantity, Short) <= 0 Then e.Row.SetColumnError("Quantity", "Quantity must be greater than 0") Else e.Row.SetColumnError("Quantity", "") End If End Sub
行が変更されたときにデータを検証するには (C#)
データセット デザイナーでデータセットを開きます。 詳細については、「 チュートリアル: データセット デザイナーでのデータセットの作成」を参照してください。
検証するテーブルのタイトル バーをダブルクリックします。 このアクションにより、 DataTableの部分クラス ファイルが作成されます。
注
データセット デザイナーは、RowChanging イベントのイベント ハンドラーを自動的に作成しません。 RowChanging イベントを処理するメソッドを作成し、テーブルの初期化メソッドでイベントをフックするコードを実行する必要があります。
次のコードを部分クラスにコピーします。
public override void EndInit() { base.EndInit(); Order_DetailsRowChanging += TestRowChangeEvent; } public void TestRowChangeEvent(object sender, Order_DetailsRowChangeEvent e) { if ((short)e.Row.Quantity <= 0) { e.Row.SetColumnError("Quantity", "Quantity must be greater than 0"); } else { e.Row.SetColumnError("Quantity", ""); } }
変更された行を取得するには
データ テーブル内の各行には、DataRowState列挙体の値を使用してその行の現在の状態を追跡するRowState プロパティがあります。 データセットまたはデータ テーブルから変更された行を返すには、DataSetまたはDataTableのGetChanges
メソッドを呼び出します。 データセットのHasChanges メソッドを呼び出すことで、GetChanges
を呼び出す前に変更が存在することを確認できます。
注
データセットまたはデータ テーブルへの変更をコミットした後 ( AcceptChanges メソッドを呼び出すことによって)、 GetChanges
メソッドはデータを返しません。 アプリケーションで変更された行を処理する必要がある場合は、 AcceptChanges
メソッドを呼び出す前に変更を処理する必要があります。
データセットまたはデータ テーブルの GetChanges メソッドを呼び出すと、変更されたレコードのみを含む新しいデータセットまたはデータ テーブルが返されます。 特定のレコード (たとえば、新しいレコードのみ、変更されたレコードのみ) を取得する場合は、パラメーターとして DataRowState 列挙体の値を GetChanges
メソッドに渡すことができます。
DataRowVersion列挙体を使用して、さまざまなバージョンの行にアクセスします (たとえば、行を処理する前の元の値)。
データセットから変更されたすべてのレコードを取得するには
データセットの GetChanges メソッドを呼び出します。
次の例では、
changedRecords
という名前の新しいデータセットを作成し、dataSet1
という別のデータセットから変更されたすべてのレコードを設定します。
変更されたすべてのレコードをデータ テーブルから取得するには
DataTable の GetChanges メソッドを呼び出します。
次の例では、
changedRecordsTable
という名前の新しいデータ テーブルを作成し、dataTable1
という別のデータ テーブルから変更されたすべてのレコードを設定します。
特定の行の状態を持つすべてのレコードを取得するには
データセットまたはデータ テーブルの
GetChanges
メソッドを呼び出し、引数として DataRowState 列挙値を渡します。次の例では、
addedRecords
という名前の新しいデータセットを作成し、dataSet1
データセットに追加されたレコードのみを設定する方法を示します。次の例は、
Customers
テーブルに最近追加されたすべてのレコードを返す方法を示しています。
DataRow の元のバージョンにアクセスする
データ行に変更が加えられた場合、データセットは元の (Original) バージョンと新しい (Current) バージョンの両方の行を保持します。 たとえば、 AcceptChanges
メソッドを呼び出す前に、アプリケーションは ( DataRowVersion 列挙で定義されている) レコードのさまざまなバージョンにアクセスし、それに応じて変更を処理できます。
注
行の異なるバージョンは、編集された後、および AcceptChanges
メソッドが呼び出される前にのみ存在します。 AcceptChanges
メソッドが呼び出された後、現在のバージョンと元のバージョンは同じです。
列インデックス (または列名) と共に DataRowVersion 値を渡すと、その列の特定の行バージョンの値が返されます。 変更された列は、 ColumnChanging および ColumnChanged イベント中に識別されます。 これは、検証のためにさまざまな行バージョンを調べるのに適したタイミングです。 ただし、制約を一時的に中断した場合、それらのイベントは発生せず、どの列が変更されたかをプログラムで識別する必要があります。 これを行うには、 Columns コレクションを反復処理し、さまざまな DataRowVersion 値を比較します。
レコードの元のバージョンを取得するには
返す行の DataRowVersion を渡して、列の値にアクセスします。
次の例は、DataRowVersion値を使用して、DataRow内の
CompanyName
フィールドの元の値を取得する方法を示しています。
DataRow の現在のバージョンにアクセスする
レコードの現在のバージョンを取得するには
列の値にアクセスし、返す行のバージョンを示すパラメーターをインデックスに追加します。
次の例は、DataRowVersion値を使用して、DataRow内の
CompanyName
フィールドの現在の値を取得する方法を示しています。