次の方法で共有


DataSet の内容のマージ

DatasetMerge メソッドを使用して、DataSetDataTable、または DataRow の配列の内容を既存の DataSet にマージできます。一部の係数およびオプションは、新しいデータを既存の DataSet にマージする方法に影響します。

主キー

マージによって新しいデータとスキーマを受け取るテーブルに主キーがある場合、受信データによる新しい行を元の主キーの値が受信データの主キーの値と同じである既存の行と一致させます。受信スキーマの列が既存のスキーマの列と一致する場合、既存の行にあるデータが変更されます。既存のスキーマと一致しない列は、MissingSchemaAction パラメータに基づいて無視または追加されます (このトピックの "MissingSchemaAction" を参照)。主キーの値が既存の行と一致しない新しい行は、既存のテーブルに追加されます。

受信する行または既存する行の行状態が Added の場合、元の行バージョンがないため、追加された行の現在の主キーの値を使用して、その 2 つの行の主キーの値を一致させます。

受信テーブルと既存のテーブルに名前が同じでも、データ型が異なる列が含まれている場合、例外がスローされ、DataSetMergeFailed イベントが発生します。受信テーブルと既存のテーブルに主キーが定義されても、その対象の列が異なる場合、例外がスローされ、DataSet の MergeFailed イベントが発生します。

マージによって新しいデータを受け取るテーブルに主キーがない場合、受信データの新しい行とそのテーブルの既存の行は一致しません。その代わりに新しい行が既存のテーブルに追加されます。

preserveChanges

DataSetDataTable、または DataRow の各配列を Merge メソッドに渡すと、オプション パラメータを含めることができます。そのパラメータを使用して、変更内容を既存の DataSet に保存するかどうか、および受信データで見つかった新しいスキーマの要素を処理する方法を指定します。受信データの後に続く最初のオプション パラメータは、Boolean 型のフラグ preserveChanges で、変更内容を既存の DataSet に保存するかどうかを指定します。preserveChanges フラグを true に設定した場合、受信する値は既存する行の現在の行バージョンで既存の値に上書きしません。preserveChanges フラグを false に設定した場合、受信する値は既存する行の現在の行バージョンで既存の値に上書きします。preserveChanges フラグを指定しない場合、既定では false に設定されます。行バージョンの詳細については、「行の状態とバージョン」を参照してください。

preserveChangestrue にすると、既存する行のデータは既存する行の行バージョンで保存されますが、既存する行の元の行バージョンには受信する行の元の行バージョンのデータが上書きされます。既存する行の RowState は、Modified に設定されます。適用する例外を次に示します。

  • 既存する行の RowStateDeleted の場合、この RowStateDeleted のままで Modified には設定されません。この場合、受信する行のデータは既存する行の元の行バージョンで保存され、既存する行の元の行バージョンに上書きします (受信する行の RowStateAdded でない場合)。
  • 受信する行の RowStateAdded の場合、受信する行が元の行バージョンでないため、既存する行の元の行バージョンのデータには、受信する行のデータで上書きされません。

preserveChangesfalse にすると、既存する行の現在または元の行バージョンは、受信する行のデータで上書きされ、既存する行の RowState は受信する行の RowState に設定されます。適用する例外を次に示します。

  • 受信する行の RowStateUnchanged で、既存する行の RowState が ModifiedDeleted、または Added の場合、既存する行の RowStateModified に設定されます。
  • 受信する行の RowStateAdded で、既存する行の RowStateUnchangedModified、または Deleted の場合、既存する行の RowStateModified に設定されます。また、受信する行が元の行バージョンでないため、既存する行の元の行バージョンのデータは、受信する行のデータで上書きされません。

MissingSchemaAction

Merge メソッドのオプションの MissingSchemaAction パラメータを使用して、既存の DataSet の一部ではない受信データのスキーマ要素を Merge で処理する方法を指定できます。

MissingSchemaAction のオプションの説明を次の表に示します。

MissingSchemaAction 説明
Add 新しいスキーマ情報を DataSet に追加し、受信する値を新しい列に読み込みます。これは、既定の設定です。
AddWithKey 新しいスキーマおよび主キーの情報を DataSet に追加し、受信する値を新しい列に読み込みます。
Error 一致しないスキーマ情報が見つかった場合、例外をスローします。
Ignore 新しいスキーマ情報を無視します。

制約

Merge メソッドを使用すると、すべての新しいデータが既存の DataSet に追加されるまで制約がチェックされません。新しいデータを追加すると、DataSet の現在の値に制約が適用されます。制約違反のためにスローされる例外を処理できるようにコードが記述されていることを確認する必要があります。

たとえば、DataSet に既存する行が Unchanged で、主キーの値が 1 の場合に、受信する行が Modified で、元の主キーの値が 2、現在の主キーの値が 1 の状態でマージ操作を行うと、元の主キーの値が異なるため、既存する行と受信する行は一致と見なされません。マージが完了し、制約がチェックされると、現在の主キーの値が主キー列の UNIQUE 制約に違反するため、例外がスローされます。

スキーマが異なる 2 つの DataSet オブジェクトを、その 2 つの受信 DataSet オブジェクトのスキーマを組み合わせて、1 つの DataSet にマージするコード例を次に示します。

Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")

Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn)

nwindConn.Open()

Dim custDS As DataSet = New DataSet()
custDA.FillSchema(custDS, SchemaType.Source, "Customers")
custDA.Fill(custDS, "Customers")

Dim orderDS As DataSet = New DataSet()
orderDS.ReadXml("Orders.xml", XmlReadMode.ReadSchema)
orderDS.AcceptChanges()

nwindConn.Close()

custDS.Merge(orderDS, True, MissingSchemaAction.AddWithKey)
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");

SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn);

nwindConn.Open();

DataSet custDS = new DataSet();
custDA.FillSchema(custDS, SchemaType.Source, "Customers");
custDA.Fill(custDS, "Customers");

DataSet orderDS = new DataSet();
orderDS.ReadXml("Orders.xml", XmlReadMode.ReadSchema);
orderDS.AcceptChanges();

nwindConn.Close();

custDS.Merge(orderDS, true, MissingSchemaAction.AddWithKey);

更新内容を含む既存の DataSet を取得し、その更新内容を DataAdapter に渡してデータ ソースで処理するコード例を次に示します。その後、その結果が元の DataSet にマージされます。エラーとなった変更内容を拒否した後、マージされた変更内容が AcceptChanges を使用してコミットされます。

  Dim custTable As DataTable = custDS.Tables("Customers")

  ' Make modifications to the Customers table.

  ' Get changes to the DataSet.
  Dim updDS As DataSet = custDS.GetChanges()

  ' Add an event handler to handle the errors during Update.
  AddHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)

  nwindConn.Open()
  custDA.Update(updDS, "Customers")
  nwindConn.Close()

  ' Merge the updates.
  custDS.Merge(updDS, true, MissingSchemaAction.Add)

  ' Reject changes on rows with errors and clear the error.
  Dim errRows() As DataRow = custDS.Tables("Customers").GetErrors()
  Dim errRow As DataRow
  For Each errRow In errRows
    errRow.RejectChanges()
    errRow.RowError = Nothing
  Next

  ' Commit the changes.
  custDS.AcceptChanges()


Private Shared Sub OnRowUpdated(sender As Object, args As SqlRowUpdatedEventArgs)
  If args.Status = UpdateStatus.ErrorsOccurred
    args.Row.RowError = args.Errors.Message
    args.Status = UpdateStatus.SkipCurrentRow
  End If
End Sub
[C#]
  DataTable custTable = custDS.Tables["Customers"];

  // Make modifications to the Customers table.

  // Get changes to the DataSet.
  DataSet updDS = custDS.GetChanges();

  // Add an event handler to handle the errors during Update.
  custDA.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);

  nwindConn.Open();
  custDA.Update(updDS, "Customers");
  nwindConn.Close();

  // Merge the updates.
  custDS.Merge(updDS, true, MissingSchemaAction.Add);

  // Reject changes on rows with errors and clear the error.
  DataRow[] errRows = custDS.Tables["Customers"].GetErrors();
  foreach (DataRow errRow in errRows)
  {
    errRow.RejectChanges();
    errRow.RowError = null;
  }

  // Commit the changes.
  custDS.AcceptChanges();


protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
{
  if (args.Status == UpdateStatus.ErrorsOccurred)
  {
    args.Row.RowError = args.Errors.Message;
    args.Status = UpdateStatus.SkipCurrentRow;
  }
}

参照

DataSet の作成および使用 | MissingSchemaAction 列挙体 | 行の状態とバージョン