MergeWith Method
The MergeWith method merges data from a refreshed (non-observable) IDataSet into the current
observable data set (IObservableDataSet).
It delegates the merge process to an observable merge handler selected from IObservableMergeOptions.
This method is commonly used in two scenarios:
Refresh merge: merge data received from an external source (database / service) into an existing observable data set.
This is typically used during the data search action to refresh UI-bound data after reloading from the database.
Post-save merge: merge server-returned values (identity columns, rowversion, computed fields) into the observable data set
after a successful save (when using MergeMode.PostSave in the observable merge options).
/// <summary>
/// Merges observable data set with data from refreshed data set
/// </summary>
/// <param name="currentObservableDataSet">Current observable data set</param>
/// <param name="refreshedDataSet">Refreshed data set</param>
/// <param name="observableMergeOptions">Observable merge options</param>
public static IObservableDataSetMergeResult MergeWith(this IObservableDataSet? currentObservableDataSet, IDataSet? refreshedDataSet, IObservableMergeOptions? observableMergeOptions = null)
Namespace: PocoDataSet.ObservableExtensions
Assembly: PocoDataSet.ObservableExtensions.dll
The following examples demonstrate both Refresh and PostSave merge scenarios for observable data sets.
// 1. Create observable data set with a newly added row (client-side)
IObservableDataSet currentObservableDataSet = new ObservableDataSet();
IObservableDataTable departmentObservableDataTable = currentObservableDataSet.AddNewTable("Department");
departmentObservableDataTable.AddColumn("Id", DataTypeNames.INT32);
departmentObservableDataTable.AddColumn("Name", DataTypeNames.STRING);
IObservableDataRow departmentObservableDataRow = departmentObservableDataTable.AddNewRow();
departmentObservableDataRow["Id"] = 1;
departmentObservableDataRow["Name"] = "Sales";
departmentObservableDataRow.AcceptChanges(); // put row into Unchanged state
// 2. Create a refreshed data set returned from database / service (non-observable)
IDataSet refreshedDataSet = DataSetFactory.CreateDataSet();
IDataTable departmentRefreshedDataTable = refreshedDataSet.AddNewTable("Department");
departmentRefreshedDataTable.AddColumn("Id", DataTypeNames.INT32);
departmentRefreshedDataTable.AddColumn("Name", DataTypeNames.STRING);
IDataRow departmentRefreshedDataRow = departmentRefreshedDataTable.AddNewRow();
departmentRefreshedDataRow["Id"] = 1;
departmentRefreshedDataRow["Name"] = "Sales and Marketing";
// 3. Merge refreshed values into the current observable data set (Refresh mode)
IObservableMergeOptions observableMergeOptions = new ObservableMergeOptions();
observableMergeOptions.MergeMode = MergeMode.Refresh;
IObservableDataSetMergeResult mergeResult = currentObservableDataSet.MergeWith(refreshedDataSet, observableMergeOptions);
// 4. Current observable row now has refreshed values "Sales and Marketing"
string? name = (string?)departmentObservableDataTable.Rows[0]["Name"];
Post-save merge is typically used immediately after saving a changeset to the database. The database may generate or update values such as identity keys, rowversion, computed columns, or trigger-populated fields.
// 1. Create observable data set with a newly added row (client-side)
IObservableDataSet observableDataSet = new ObservableDataSet();
IObservableDataTable departmentObservableDataTable = observableDataSet.AddNewTable("Department");
departmentObservableDataTable.AddColumn("Id", DataTypeNames.INT32); // identity in DB
departmentObservableDataTable.AddColumn("Name", DataTypeNames.STRING);
departmentObservableDataTable.AddColumn("RowVersion", DataTypeNames.BINARY); // rowversion/timestamp in DB
IObservableDataRow departmentObservableDataRow = departmentObservableDataTable.AddNewRow();
departmentObservableDataRow["Name"] = "Engineering";
// At this moment the row is typically in Added state and has no identity / rowversion yet.
// Get correlation data from row
Guid clientKey = departmentObservableDataRow.GetDataFieldValue<Guid>(SpecialColumnNames.CLIENT_KEY);
// 2. Build a server-returned data set after save
// This data set contains the database-generated values for the same logical row.
IDataSet postSaveDataSet = DataSetFactory.CreateDataSet();
IDataTable postSaveDepartmentDataTable = postSaveDataSet.AddNewTable("Department");
postSaveDepartmentDataTable.AddColumn("Id", DataTypeNames.INT32);
postSaveDepartmentDataTable.AddColumn("Name", DataTypeNames.STRING);
postSaveDepartmentDataTable.AddColumn("RowVersion", DataTypeNames.BINARY);
IDataRow postSaveDepartmentDataRow = postSaveDepartmentDataTable.AddNewRow();
postSaveDepartmentDataRow["Id"] = 10; // Imitate identity generated by DB
postSaveDepartmentDataRow["Name"] = "Engineering";
postSaveDepartmentDataRow["RowVersion"] = new byte[] { 1, 0, 0, 0, 0, 0, 0, 0 };
// Imitate correlation between observable and saved rows
postSaveDepartmentDataRow[SpecialColumnNames.CLIENT_KEY] = clientKey;
// 3. Merge server-returned values into the observable data set using PostSave mode
IObservableMergeOptions observableMergeOptions = new ObservableMergeOptions();
observableMergeOptions.MergeMode = MergeMode.PostSave;
IObservableDataSetMergeResult mergeResult = observableDataSet.MergeWith(postSaveDataSet, observableMergeOptions);
// 4. Current row now has server-generated values (identity/rowversion) and is typically accepted as Unchanged by the merge handlers
int id = departmentObservableDataTable.Rows[0].GetDataFieldValue<int>("Id"); // 10
byte[]? rowVersion = departmentObservableDataTable.Rows[0].GetDataFieldValue<byte[]>("RowVersion");
MergeWith repeatedly with the same IObservableMergeOptions instance, the method clears
the previous result before merging so the returned merge result always describes the most recent merge.
Table of Content POCO DataSet Observable Data Set Members
Business Process Programming in .Net
© 2004–2026 Laskarzhevsky Software Inc.
Unless otherwise noted, the content of this website is licensed under the
Creative Commons Attribution 4.0 International License (CC BY 4.0).
Code examples are provided under the MIT License.
You are free to share and adapt the material provided that appropriate
credit is given and any modifications are clearly indicated.
The information provided on this website is for educational purposes only.
The author and publisher make no warranties regarding the completeness
or suitability of the information and are not responsible for any damages
resulting from its use.