C# Datatable合并并拒绝未按预期工作的更改
我正在处理一个winform,其中包含2个类似的数据网格,每个数据网格都将其数据源设置为同一表的不同实例。出于测试目的,这些表既有不同的记录,也有相似的记录,每个记录填写不同的单元格 1-调用Datatable.Merge时,目标表会获取缺少的行,但初始行的空单元格不会从源表的相应单元格中更新 2-在目标表上调用Datatable.RejectChanges时,合并添加的行不会被删除,这是一个问题,但这次,初始行的空单元格会从源表的相应单元格中正确更新,这在合并时可能会发生 用于填充表格的函数:C# Datatable合并并拒绝未按预期工作的更改,c#,winforms,datatable,C#,Winforms,Datatable,我正在处理一个winform,其中包含2个类似的数据网格,每个数据网格都将其数据源设置为同一表的不同实例。出于测试目的,这些表既有不同的记录,也有相似的记录,每个记录填写不同的单元格 1-调用Datatable.Merge时,目标表会获取缺少的行,但初始行的空单元格不会从源表的相应单元格中更新 2-在目标表上调用Datatable.RejectChanges时,合并添加的行不会被删除,这是一个问题,但这次,初始行的空单元格会从源表的相应单元格中正确更新,这在合并时可能会发生 用于填充表格的函数:
private bool OpenFile(Datatable table)
{
if (OFD.ShowDialog() == DialogResult.OK) // OFD is OpenFileDialog
{
if (UserPrompt.ShowDialog() == DialogResult.OK) // UserPrompt is a custom input dialog for user credentials
{
try
{
// code to fill table not shown for readability, works well anyway
table.AcceptChanges(); // otherwise all the records are deleted after RejectChanges, including the initial ones
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Operation Canceled", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
return false;
}
合并功能:
private void menuMerge1_Click(object sender, EventArgs e)
{
Table1.Merge(Table2, true);
if (MessageBox.Show("Table 2 merged to table 1. Save changes? Choosing no will cancel the merging.", "Keep or Discard Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.OK)
Save(Table1); // saving to file, custom function
else Table1.RejectChanges();
}
首先调用OpenFile函数,然后调用merge,就是这样
我试过:
- 刷新DataGridView
- 重置DataGridView的数据源
- 合并后在目标上调用AcceptChanges
提前感谢您的任何见解 好的,首先是DataTable.Merge不会引发事件,这意味着RejectChanges只对修改过的行起作用,添加的行被标记为未更改。解决方案是编写一个自定义合并函数。假设PK是第一个单列,则可以很好地处理类似的表:
private bool Merge(DataTable target, DataTable source, bool preserve)
{
if (!preserve)
{
target.Merge(source, false);
return true;
}
else
{
DataRow drTargetMatch;
DataRow drNew;
int numCol = source.Columns.Count;
int index = 1;
try
{
foreach (DataRow dr in source.Rows)
{
drTargetMatch = target.Rows.Find(dr[0]);
if (drTargetMatch == null) // source row does not exist in target, add a copy
{
drNew = target.NewRow();
drNew.ItemArray = dr.ItemArray;
target.Rows.Add(drNew);
}
else // source row exists in target, update empty values
{
for (index = 1; index < numCol; index++) // start at 1 since we don't update PK
{
if (drTargetMatch.IsNull(index) && !dr.IsNull(index))
drTargetMatch[index] = dr[index];
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Operation Canceled", MessageBoxButtons.OK, MessageBoxIcon.Error);
target.RejectChanges();
return false;
}
return true;
}
}
私有布尔合并(数据表目标、数据表源、布尔保留)
{
如果(!保留)
{
target.Merge(源,false);
返回true;
}
其他的
{
数据行drTargetMatch;
数据行drNew;
int numcoll=source.Columns.Count;
int指数=1;
尝试
{
foreach(source.Rows中的数据行dr)
{
drTargetMatch=target.Rows.Find(dr[0]);
如果(drTargetMatch==null)//目标中不存在源行,请添加副本
{
drNew=target.NewRow();
drNew.ItemArray=dr.ItemArray;
target.Rows.Add(drNew);
}
否则//目标中存在源行,请更新空值
{
对于(index=1;index
好的,首先是DataTable.Merge不会引发事件,这意味着RejectChanges只对修改过的行起作用,添加的行被标记为未更改。解决方案是编写一个自定义合并函数。假设PK是第一个单列,则可以很好地处理类似的表:
private bool Merge(DataTable target, DataTable source, bool preserve)
{
if (!preserve)
{
target.Merge(source, false);
return true;
}
else
{
DataRow drTargetMatch;
DataRow drNew;
int numCol = source.Columns.Count;
int index = 1;
try
{
foreach (DataRow dr in source.Rows)
{
drTargetMatch = target.Rows.Find(dr[0]);
if (drTargetMatch == null) // source row does not exist in target, add a copy
{
drNew = target.NewRow();
drNew.ItemArray = dr.ItemArray;
target.Rows.Add(drNew);
}
else // source row exists in target, update empty values
{
for (index = 1; index < numCol; index++) // start at 1 since we don't update PK
{
if (drTargetMatch.IsNull(index) && !dr.IsNull(index))
drTargetMatch[index] = dr[index];
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Operation Canceled", MessageBoxButtons.OK, MessageBoxIcon.Error);
target.RejectChanges();
return false;
}
return true;
}
}
私有布尔合并(数据表目标、数据表源、布尔保留)
{
如果(!保留)
{
target.Merge(源,false);
返回true;
}
其他的
{
数据行drTargetMatch;
数据行drNew;
int numcoll=source.Columns.Count;
int指数=1;
尝试
{
foreach(source.Rows中的数据行dr)
{
drTargetMatch=target.Rows.Find(dr[0]);
如果(drTargetMatch==null)//目标中不存在源行,请添加副本
{
drNew=target.NewRow();
drNew.ItemArray=dr.ItemArray;
target.Rows.Add(drNew);
}
否则//目标中存在源行,请更新空值
{
对于(index=1;index
I更好的方法是先询问用户,然后进行合并,而不是反过来。您将为大型表节省宝贵的处理器时间。@Abdul Rehman说:没错。一旦我找到了一种可靠的合并表的方法,我就会改变这一点:)我最好的方法是先询问用户,然后继续合并,而不是反过来。您将为大型表节省宝贵的处理器时间。@Abdul Rehman说:没错。一旦找到可靠的合并表的方法,我将立即更改此选项:)