繁体   English   中英

从DataTable访问已删除的行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM