如何以编程方式从 DataTable 中删除 DataColumn
How to remove DataColumn from DataTable programmatically
我有密码
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);
}
}
我想从 collection 中删除一些 "things",如果它们在另一个 collection 中找不到。
当我运行上述程序时,我得到
Iteration may not execute as collection was modified
"Collection was modified" - 因为删除必须已命中
那有什么方法可以达到这样的效果呢?
我能想到的是记下所有要删除的 "things" 然后
foreach( aThing in all_things_to_remove)
remove_from_collection(aThing)
但以上对我来说似乎不是一个好方法,因为我必须再做一次循环并且正在使用额外的内存
您不能在使用 foreach 循环枚举集合时从集合中删除项目。使用 Collection.ToArray()
和 运行 制作集合的副本,并在副本上进行 foreach 并将您的项目从实际集合中删除。
由于 DataTable.Columns 没有 ToArray
或 ToList
方法,您可以使用 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);
}
}
在这种特定情况下,您要遍历一个包含几列的小集合,您可以只创建一个新集合(通过 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);
}
另一种方法是在删除列后降低索引。
for (int i = 0; i < datatable.Columns.Count; i++)
{
if (datatable.Columns[i].ColumnName.Contains("Column"))
{
datatable.Columns.RemoveAt(i);
i--;
}
}
if (dt.Columns.Contains("RecordID")){
dt.Columns.Remove("RecordID");
dt.AcceptChanges();
}
我有密码
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);
}
}
我想从 collection 中删除一些 "things",如果它们在另一个 collection 中找不到。
当我运行上述程序时,我得到
Iteration may not execute as collection was modified
"Collection was modified" - 因为删除必须已命中
那有什么方法可以达到这样的效果呢?
我能想到的是记下所有要删除的 "things" 然后
foreach( aThing in all_things_to_remove)
remove_from_collection(aThing)
但以上对我来说似乎不是一个好方法,因为我必须再做一次循环并且正在使用额外的内存
您不能在使用 foreach 循环枚举集合时从集合中删除项目。使用 Collection.ToArray()
和 运行 制作集合的副本,并在副本上进行 foreach 并将您的项目从实际集合中删除。
由于 DataTable.Columns 没有 ToArray
或 ToList
方法,您可以使用 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);
}
}
在这种特定情况下,您要遍历一个包含几列的小集合,您可以只创建一个新集合(通过 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);
}
另一种方法是在删除列后降低索引。
for (int i = 0; i < datatable.Columns.Count; i++)
{
if (datatable.Columns[i].ColumnName.Contains("Column"))
{
datatable.Columns.RemoveAt(i);
i--;
}
}
if (dt.Columns.Contains("RecordID")){
dt.Columns.Remove("RecordID");
dt.AcceptChanges();
}