How to maintain deleted RowState across DataSet merges?
Please consider the following situation:
- DataSet A contains the current set of data found in some data source.
- DataSet B contains future changes to the data found in A, which have not yet been applied to A.
Using .NET's DataSet.Merge(DataSet)
method, we can apply B to A, creating a new DataSet C, i.e. C = A.Merge(B)
.
The problem with the DataSet.Merge(DataSet)
Merge method is that, for any row r which is flagged as Deleted in B, r will be flagged as Modifi开发者_如何转开发ed in C. Whilst, clearly, r in C should be flagged Deleted as well.
A solution which would work, but I find unappealing, is to manually enumerate across all Deleted rows in B, and use their identifier to find the same row in C, thereafter changing the RowState of that row in C to Deleted as well.
What would be the proper solution to the above problem?
I have been playing around with datasets and came up with the democode below (based on MSDN) to test some of the things you ask. (.net framework 4.0 VS2010)
What I find is that merge is void so when looking at your question we have A.Merge(B) and A is merged with B.
Normal merging (without the preserveChanges flag) makes B leading so when something is deleted in B and it was present in A it will also be deleted in the new A. If I read your question correctly this is the behaviour desired by you. (testoutput A)
If you have set the preservechanges flag to True than strange things start to happen, the deleted flag for example will be a modified in the new A. (testoutput B)
If you have the preservechnages flag set to true, set it to false. As far as I can tell the default behaviour is what you want and you that isn't what you see. I suspect something else to be wrong, hope this helps you in the right direction
private static void DemonstrateMergeTable()
{
// Create a DataSet with one table, two columns, and data.
DataSet originalDataSet = new DataSet("dataSet");
DataSet mergeDataSet = new DataSet("mergeSet");
DataTable originalTable = CreateItemsTable(originalDataSet);
DataTable mergeTable = CreateTableToMergeWith(originalTable, mergeDataSet);
CreateTestSets(originalTable, mergeTable);
PrintValues(originalDataSet, "Original values");
PrintValues(mergeDataSet, "Table to merge with");
// Merge the table into the DataSet
Console.WriteLine("Merging");
//originalDataSet.Merge(mergeTable,false,MissingSchemaAction.Add);
//originalDataSet.Merge(mergeTable,true, MissingSchemaAction.Add);
originalDataSet.Merge(mergeTable);
PrintValues(originalDataSet, "Merged With table.");
}
private static void CreateTestSets(DataTable originalTable, DataTable mergeTable)
{
// a new row to the mergetable, no matching row in the original
mergeTable.Rows.Add(new Object[] { 30, 0 });
//deletedRow in original, added row in mergetable
originalTable.Rows[0].Delete(); //id = 0
mergeTable.Rows.Add(new Object[] { 0, 100 });
//deletedRow in mergeset, corresponding row in original
mergeTable.Rows[0].Delete(); //id = 5
//deletedRow in original, corrosponding row in merging
originalTable.Rows[6].Delete();
}
private static DataTable CreateItemsTable(DataSet dataSet)
{
DataTable table = new DataTable("Items");
// Add columns
DataColumn c1 = new DataColumn("id",
Type.GetType("System.Int32"), "");
DataColumn c2 = new DataColumn("Item",
Type.GetType("System.Int32"), "");
table.Columns.Add(c1);
table.Columns.Add(c2);
// DataColumn array to set primary key.
DataColumn[] keyCol = new DataColumn[1];
// Set primary key column.
keyCol[0] = c1;
table.PrimaryKey = keyCol;
// Add rows.
for (int i = 0; i < 10; i++)
{
DataRow row = table.NewRow();
row["id"] = i;
row["Item"] = i;
table.Rows.Add(row);
}
// Add table to the DataSet
dataSet.Tables.Add(table);
// Accept changes.
dataSet.AcceptChanges();
return table;
}
private static DataTable CreateTableToMergeWith(DataTable table, DataSet mergeSet)
{
DataTable t2 = table.Clone();
// Add rows.
for (int i = 5; i < 15; i++)
{
DataRow row = t2.NewRow();
row["id"] = i;
row["Item"] = i;
t2.Rows.Add(row);
}
mergeSet.Tables.Add(t2);
t2.AcceptChanges();
return t2;
}
private static void PrintValues(DataSet dataSet, string label)
{
Console.WriteLine("\n" + label);
foreach (DataTable table in dataSet.Tables)
{
PrintTable(table);
}
}
private static void PrintTable(DataTable table)
{
Console.WriteLine("TableName: " + table.TableName);
foreach (DataRow row in table.Rows)
{
DataRowState dataRowState = row.RowState;
foreach (DataColumn column in table.Columns)
{
string columnName = column.ColumnName;
Object o = dataRowState != DataRowState.Deleted ? row[column] : row[column, DataRowVersion.Original];
Console.Write("\t {0} \t:{1}",columnName, o);
}
Console.Write("\t ({0})", dataRowState);
Console.WriteLine();
}
}
TestOutput A (preservechanges = false)
Original values
TableName: Items
id :0 Item :0 (Deleted)
id :1 Item :1 (Unchanged)
id :2 Item :2 (Unchanged)
id :3 Item :3 (Unchanged)
id :4 Item :4 (Unchanged)
id :5 Item :5 (Unchanged)
id :6 Item :6 (Deleted)
id :7 Item :7 (Unchanged)
id :8 Item :8 (Unchanged)
id :9 Item :9 (Unchanged)
Table to merge with
TableName: Items
id :5 Item :5 (Deleted)
id :6 Item :6 (Unchanged)
id :7 Item :7 (Unchanged)
id :8 Item :8 (Unchanged)
id :9 Item :9 (Unchanged)
id :10 Item :10 (Unchanged)
id :11 Item :11 (Unchanged)
id :12 Item :12 (Unchanged)
id :13 Item :13 (Unchanged)
id :14 Item :14 (Unchanged)
id :30 Item :0 (Added)
id :0 Item :100 (Added)
Merging
Merged With table.
TableName: Items
id :0 Item :100 (Modified)
id :1 Item :1 (Unchanged)
id :2 Item :2 (Unchanged)
id :3 Item :3 (Unchanged)
id :4 Item :4 (Unchanged)
id :5 Item :5 (Deleted)
id :6 Item :6 (Modified)
id :7 Item :7 (Unchanged)
id :8 Item :8 (Unchanged)
id :9 Item :9 (Unchanged)
id :10 Item :10 (Unchanged)
id :11 Item :11 (Unchanged)
id :12 Item :12 (Unchanged)
id :13 Item :13 (Unchanged)
id :14 Item :14 (Unchanged)
id :30 Item :0 (Added)
Test output B (with preservechanges to true)
Original values
TableName: Items
id :0 Item :0 (Deleted)
id :1 Item :1 (Unchanged)
id :2 Item :2 (Unchanged)
id :3 Item :3 (Unchanged)
id :4 Item :4 (Unchanged)
id :5 Item :5 (Unchanged)
id :6 Item :6 (Deleted)
id :7 Item :7 (Unchanged)
id :8 Item :8 (Unchanged)
id :9 Item :9 (Unchanged)
Table to merge with
TableName: Items
id :5 Item :5 (Deleted)
id :6 Item :6 (Unchanged)
id :7 Item :7 (Unchanged)
id :8 Item :8 (Unchanged)
id :9 Item :9 (Unchanged)
id :10 Item :10 (Unchanged)
id :11 Item :11 (Unchanged)
id :12 Item :12 (Unchanged)
id :13 Item :13 (Unchanged)
id :14 Item :14 (Unchanged)
id :30 Item :0 (Added)
id :0 Item :100 (Added)
Merging
Merged With table.
TableName: Items
id :0 Item :0 (Deleted)
id :1 Item :1 (Unchanged)
id :2 Item :2 (Unchanged)
id :3 Item :3 (Unchanged)
id :4 Item :4 (Unchanged)
id :5 Item :5 (Modified)
id :6 Item :6 (Deleted)
id :7 Item :7 (Modified)
id :8 Item :8 (Modified)
id :9 Item :9 (Modified)
id :10 Item :10 (Unchanged)
id :11 Item :11 (Unchanged)
id :12 Item :12 (Unchanged)
id :13 Item :13 (Unchanged)
id :14 Item :14 (Unchanged)
id :30 Item :0 (Added)
精彩评论