【问题标题】:How to remove DataColumn from DataTable programmatically如何以编程方式从 DataTable 中删除 DataColumn
【发布时间】:2015-01-14 02:32:21
【问题描述】:

我有密码

foreach (DataColumn dataTableCol in this.dataTable.Columns)
            {
                bool columnFound = false;
                foreach (GRTColumnView uiColumn in descriptor.UIColumns)
                {
                    if (dataTableCol.ColumnName.Equals(uiColumn.Name))
                    {
                        columnFound = true;
                        break;
                    }
                }

                if (!columnFound)
                {
                    if (this.dataTable.Columns.Contains(dataTableCol.ColumnName))
                        this.dataTable.Columns.Remove(dataTableCol.ColumnName);
                }

            }

如果在另一个集合中找不到某些“东西”,我想从集合中删除它们。

当我运行上面的程序时,我得到了

由于集合被修改,迭代可能无法执行

“集合已修改” - 因为删除必须已被击中

那么有什么方法可以实现呢?

我能想到的是记下所有要删除的“东西”,然后

foreach( aThing in all_things_to_remove)
     remove_from_collection(aThing)

但上面对我来说似乎不是一个好方法,因为我必须进行另一个循环并且正在使用额外的内存

【问题讨论】:

  • @Plutonix 喜欢这个? for(inedx = this.dataTable.Columns.Count - 1 ; index >= 0 ; index++) 还是有更好的办法?

标签: c# collections datatable datacolumn datacolumncollection


【解决方案1】:

在这种特定情况下,您正在循环一个包含几列的小集合,您可以只创建一个新集合(通过ToList()),这样您就不会遍历同一个集合修改:

foreach (var dataTableCol in dataTable.Columns.Cast<DataColumn>().ToList())
{
    ...

    dataTable.Columns.Remove(dataTableCol.ColumnName);
}

推荐的方法,特别是如果集合很大,是向后枚举:

for (var i = dataTable.Columns.Count - 1; i >= 0; i--)
{
    ...

    dataTable.Columns.Remove(dataTable.Columns[i].ColumnName);
}

【讨论】:

  • 感谢您的回答。就我而言,正如您所说,收藏量很小,但是如果我的收藏量很大怎么办?有没有办法避免复制?
【解决方案2】:

在使用 foreach 循环枚举集合时,您不能从集合中删除项目。使用Collection.ToArray() 复制集合并在副本上运行 foreach 并从实际集合中删除您的项目。

由于 DataTable.Columns 没有 ToArrayToList 方法,您可以使用 CopyTo() 方法并将整个列复制到 ColumnsArray。

如果您不想创建副本,则可以使用 for 循环代替 foreach 循环。你可以这样编辑你的代码:

for (int i = 0; i < dataTable.Columns.Count; i++)
{
    bool columnFound = false;
    foreach (GRTColumnView uiColumn in descriptor.UIColumns)
    {
        if (dataTable.Columns[i].Name.Equals(uiColumn.Name))
        {
            columnFound = true;
            break;
        }
    }

    if (!columnFound)
    {
        if (this.dataTable.Columns.Contains(dataTableCol.ColumnName))
            this.dataTable.Columns.Remove(dataTableCol.ColumnName);
    }

}

【讨论】:

  • 好吧,我从错误中知道这一点。我在问一个出路。而你建议的方式,我已经在我的问题中指出了类似的方法,这对我来说听起来不太好
【解决方案3】:

另一种方法是在删除列后降低索引。

for (int i = 0; i < datatable.Columns.Count; i++)
            {
                if (datatable.Columns[i].ColumnName.Contains("Column"))
                {
                    datatable.Columns.RemoveAt(i);
                    i--;
                }
            }

【讨论】:

    【解决方案4】:
    if (dt.Columns.Contains("RecordID")){
                        dt.Columns.Remove("RecordID");
                        dt.AcceptChanges();
                    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-22
      • 2015-06-01
      • 1970-01-01
      • 2012-08-03
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多