C# 安全删除 ForEach 中的 DataRow
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2341580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Safely Removing DataRow In ForEach
提问by Hyman Kada
I don't understand why this code does not work.
我不明白为什么这段代码不起作用。
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
采纳答案by Jon Skeet
Even though DataRow.Delete
doesn't modify the state of the collection, Microsoft documentationstates that you shouldn't call it while iterating over the collection:
即使DataRow.Delete
不修改集合的状态,Microsoft 文档也指出您不应在迭代集合时调用它:
Neither Delete nor Remove should be called in a foreach loop while iterating through a DataRowCollection object. Delete nor Remove modify the state of the collection.
在遍历 DataRowCollection 对象时,不应在 foreach 循环中调用 Delete 和 Remove。Delete 或 Remove 修改集合的状态。
The best solution is usually to create a separate collection (e.g. a List<DataRow>
) of items you want to remove, and then remove them afteryou've finished iterating.
最好的解决方案通常是创建一个单独的集合(例如 a List<DataRow>
)要删除的项目,然后在完成迭代后删除它们。
This is also the solution for situations where you want to remove items from a collection, as most collections in .NET don't allow you to change the contents of the collection while you're iterating over it.
这也是您想要从集合中删除项目的情况的解决方案,因为 .NET 中的大多数集合不允许您在迭代集合时更改集合的内容。
回答by Lucero
The Rows
content changes while you are iterating if you delete one row, which renders the iteration invalid.
该Rows
内容的变化,而如果删除一行,这使得迭代无效你迭代。
You can, however, copy the rows into a collection first and then iterate over the collection and delete the rows that way. This makes sure that the iteration is not interrupted by changing data to be iterated.
但是,您可以先将行复制到集合中,然后遍历集合并以这种方式删除行。这确保迭代不会因更改要迭代的数据而中断。
回答by DOK
This applies to pretty much any collection. If you try to delete an item while looping through the collection, you will have a problem. For example, if you delete row #3, then the previous row #4 becomes row #3.
这几乎适用于任何集合。如果您在遍历集合时尝试删除项目,则会出现问题。例如,如果您删除第 #3 行,则前一行 #4 将成为第 #3 行。
回答by Thibault Falise
You cannot modify a collection while you're iterating on it using a foreach
statement.
在使用foreach
语句对其进行迭代时,您不能修改集合。
you can try something like that :
你可以尝试这样的事情:
List<DataRow> deletedRows = new List<DataRow>();
foreach (DataRow dataRow in dataTable.Rows)
{
if(true) deletedRows.Add(dataRow);
}
foreach(DataRow dataRow in deletedRows)
{
dataRow.Delete();
}
回答by Thibault Falise
Use this:
用这个:
for (int i = 0; i < myDataTable.Rows.Count; i++)
{
myDataTable[i].Delete();
}
回答by VMAtm
Safest way - use for
loop
最安全的方法 - 使用for
循环
for (int i = datatable.Rows.Count - 1; i >= 0; i--)
{
if (true)
{
datatable.Rows[i].Delete();
}
}
Don't forget to AcceptChanges
to remove all marked rows:
不要忘记AcceptChanges
删除所有标记的行:
datatable.AcceptChanges();
回答by IAbstract
Where items have a Count
, this is what I have done:
项目有一个Count
,这就是我所做的:
int Count = myTable.Rows.Count;
while (Count > 0) // replace condition with myTable.Rows.Count if unconditionally performed on all rows
{
DataRow row = myTable.Rows[0] // or however you want to find your index
// do some work
myTable.Rows.Remove(row);
// if you want to perform a check to break out of while
if (someCondition)
Count = 0;
else
Count = myTable.Rows.Count;
}
Note, that where objects have a .GetXXXX()
collection, like FileInfo
(IIRC),
deleting item contents in a foreach
is acceptable. One solution I have considered is creating an extension method that provides a .GetItems()
method.
请注意,在对象具有.GetXXXX()
集合的情况下,例如FileInfo
(IIRC),删除 a 中的项目内容foreach
是可以接受的。我考虑过的一个解决方案是创建一个提供.GetItems()
方法的扩展方法。
回答by Chris
If you call the delete method you just have to call AcceptChanges()
on the table you are modifying, after the foreach loop.
如果您调用 delete 方法,您只需AcceptChanges()
在 foreach 循环之后调用您正在修改的表。
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
The delete method simply marks the row for deletion.
delete 方法只是标记要删除的行。
http://msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx
http://msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx
回答by neverlandx
may be my answer not longer useful. exception throw in Foreach with DataRow only appear in .Net 2.0 and earlier, the reason is description at msdn http://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx
可能是我的答案不再有用。Foreach with DataRow 中的异常抛出仅出现在 .Net 2.0 及更早版本中,原因是 msdn http://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80 ).aspx
If the RowState of the row is Added, the row is removed from the table.
如果行的 RowState 为已添加,则从表中删除该行。
The RowState becomes Deleted after you use the Delete method. It remains Deleted until you call AcceptChanges.
使用 Delete 方法后,RowState 变为 Deleted。在您调用 AcceptChanges 之前,它会保持 Deleted 状态。
A deleted row can be undeleted by invoking RejectChanges.
可以通过调用 RejectChanges 来取消删除已删除的行。
to pass this problem you can call DataTable.AcceptChanges() before using foreach
要传递此问题,您可以在使用 foreach 之前调用 DataTable.AcceptChanges()
回答by Mark Macneil Bikeio
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
Please Refer the snaps to understatnd the working of it.
请参考快照以了解它的工作原理。
- Just Deleted but not removed from the DataTable.
- 刚刚删除但未从数据表中删除。
- Break point before AcceptChanges() Function.
- After Eexecuting AcceptChanges() Function.
- AcceptChanges() 函数之前的断点。
- 在执行 AcceptChanges() 函数之后。
I Hope this issue resolved now.
我希望这个问题现在解决了。