[英]Accessing deleted rows from a DataTable
我有一个父MyForm有一个MyDataTable _dt
作为成员。 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
语句:
///<summary>Gets the rows in a typed DataTable that have not been deleted.</summary>
public static EnumerableRowCollection<TRow> CurrentRows<TRow>(this TypedTableBase<TRow> 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 IEnumerable<TRow> CurrentRows(IEnumerable<TRow> 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 IEnumerable<MyRow> CurrentRows() { return Utils.CurrentRows(this); }
}
你在迭代中跳过行所做的是正确的,当我循环遍历可能被修改的DataTable时,我会定期检查RowState。
在某些情况下,我相信在行标记为已删除之前,您需要原始行值。 检索特定数据行值时,有一个辅助索引选项。
string st = dr["columnname", DataRowVersion.Original].ToString(); // c#
dim st As String = dr("columnname", DataRowVersion.Original).ToString() ' vb.net
我过去曾多次坚持过这个问题。
就GetChanges(RowState)方法而言,不要忘记检查null返回,如果没有该RowState的行,则返回的DataTable为null(我认为它应该返回一个零行的表)
你必须检查:
_dt.DefaultView.RowStateFilter
我认为默认设置不会显示已删除的行,也许你会在某处更改它。
您始终可以创建一个额外的RowView并控制其过滤器并在View上循环。
使用GetChanges():
foreach (myDataTableRow row in _dt.GetChanges(DataRowState.Added))
{
sbFilter.Append("'" + row.info + "',");
}
如果要全部添加和修改,请在添加和修改时使用按位OR:
foreach (myDataTableRow row in
_dt.GetChanges(DataRowState.Added | DataRowState.Modified))
{
sbFilter.Append("'" + row.info + "',");
}
我不确定这一点,但我认为如果在删除一行或多行后调用_dt.AcceptChanges()
,则在遍历数据表的Rows集合时,您将不会“看到”已删除的行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.