我有一个具有MyDataTable _dt
作为成员的父WinForm .MyDataTable类型是在Visual Studio 2005中的"类型化数据集"设计器工具中创建的(MyDataTable继承自DataTable) _dt
,通过ADO.NET从db填充.基于表单中用户交互的更改,我从表中删除了一行,如下所示:
_dt.FindBySomeKey(_someKey).Delete();
稍后,_dt
将值传递给对话框表单.从那里,我需要扫描所有行来构建一个字符串:
foreach (myDataTableRow row in _dt) { sbFilter.Append("'" + row.info + "',"); }
问题是在删除后执行此操作时,会引发以下异常:
DeletedRowInaccessibleException: Deleted row information cannot be accessed through the row.
我目前正在使用的工作(感觉就像一个黑客)如下:
foreach (myDataTableRow row in _dt) { if (row.RowState != DataRowState.Deleted && row.RowState != DataRowState.Detached) { sbFilter.Append("'" + row.info + "',"); } }
我的问题:这是正确的方法吗?为什么foreach循环访问通过该Delete()
方法标记的行?
该Delete
方法标记一行删除; 在你打电话之前,这行不会被删除AcceptChanges
.
相反,打电话
请注意,如果您调用_dt.Rows.Remove(_dt.FindBySomeKey(_someKey))
,也接受改变.
信不信由你,Rows.Remove
将完全删除行,而row.Delete()
不会. Rows.Remove
,该行将永久消失,并且不会被DataAdapter从数据库中删除.
在C#3中,您可以if
使用以下扩展方法替换语句:
///Gets the rows in a typed DataTable that have not been deleted. public static EnumerableRowCollectionCurrentRows (this TypedTableBase table) where TRow : DataRow { return table.Where(r => r.RowState != DataRowState.Deleted); } foreach (myDataTableRow row in _dt.CurrentRows()) { ...
这是一个C#2版本:
static class Utils { public static IEnumerableCurrentRows(IEnumerable table) where TRow : DataRow { foreach(TRow row in table) { if (row.RowState != DataRowState.Deleted) yield return row; } } } foreach (myDataTableRow row in Utils.CurrentRows(_dt)) {
您还可以将此函数放入类型表的分部类中:
partial class MyTable { public IEnumerableCurrentRows() { return Utils.CurrentRows(this); } }