Hello! Prompt, please, why HasChanges (at DataSet) produces false after Merge of two tables? In the case when the data is replaced by the key, and in theory, the DataRowState change should work. On MSDN they write that it is necessary to set false in the preserveChanges parameter - it doesn't help

Here is a small example:

var ds = new DataSet(); var dt1 = new DataTable(); dt1.Columns.Add("id", typeof (int)); dt1.Columns.Add("name", typeof (string)); dt1.PrimaryKey = new[] {dt1.Columns["id"]}; dt1.Rows.Add(1, "name1"); dt1.Rows.Add(2, "name2"); ds.Tables.Add(dt1); ds.AcceptChanges(); var dt2 = new DataTable(); dt2.Columns.Add("id", typeof(int)); dt2.Columns.Add("name", typeof(string)); dt2.PrimaryKey = new[] { dt2.Columns["id"] }; dt2.Rows.Add(1, "name100"); dt2.Rows.Add(2, "name200"); dt2.AcceptChanges(); dt1.Merge(dt2, false); Console.WriteLine(ds.HasChanges()); Console.ReadKey(); 
  • The parameter false means NOT to save changes. Set true . - Alexander Petrov
  • Test this example and see in the debugger how the dt1 table will look like, if you set true for Merge - Bogdan Rudnytskyi

1 answer 1

I did not find any adequate solutions and explanations, I decided to write my Merge:

 public static void UserMerge(this DataTable dst, DataTable src) { if (dst.PrimaryKey.Length == 0) throw new ArgumentException("В таблице источнике отсутствует ключ"); foreach (DataRow row in src.Select()) { var res = GetSearch(row, dst); if (res != null) { foreach (DataColumn col in src.Columns) if (dst.Columns.Contains(col.ColumnName)) res[col.ColumnName] = row[col.ColumnName]; } else { var newRow = dst.NewRow(); foreach (DataColumn col in src.Columns) if (dst.Columns.Contains(col.ColumnName)) newRow[col.ColumnName] = row[col.ColumnName]; dst.Rows.Add(newRow); } } } private static DataRow GetSearch(DataRow row, DataTable dst) { object[] search = new object[dst.PrimaryKey.Length]; for (int i = 0; i < dst.PrimaryKey.Length; ++i) if (row.Table.Columns.Contains(dst.PrimaryKey[i].ColumnName)) search[i] = row[dst.PrimaryKey[i].ColumnName]; return dst.Rows.Find(search); }