我不明白为什么这段代码不起作用。
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
答案 0 :(得分:47)
最安全的方式 - 使用for
循环
for (int i = datatable.Rows.Count - 1; i >= 0; i--)
{
if (true)
{
datatable.Rows[i].Delete();
}
}
不要忘记AcceptChanges
删除所有标记的行:
datatable.AcceptChanges();
答案 1 :(得分:32)
即使DataRow.Delete
没有修改集合的状态,Microsoft documentation也指出在迭代集合时不应该调用它:
在迭代DataRowCollection对象时,不应在foreach循环中调用Delete或Remove。删除也不删除修改集合的状态。
最好的解决方案通常是创建一个单独的集合(例如List<DataRow>
)要删除的项目,然后在完成迭代后删除它们。
对于要从集合中删除项目的情况,这也是一种解决方案,因为.NET中的大多数集合都不允许您在迭代时更改集合的内容。
答案 2 :(得分:19)
在使用foreach
语句对其进行迭代时,无法修改集合。
你可以尝试这样的事情:
List<DataRow> deletedRows = new List<DataRow>();
foreach (DataRow dataRow in dataTable.Rows)
{
if(true) deletedRows.Add(dataRow);
}
foreach(DataRow dataRow in deletedRows)
{
dataRow.Delete();
}
答案 3 :(得分:9)
如果你调用delete方法,你只需要在foreach循环之后调用你正在修改的表上的AcceptChanges()
。
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
delete方法只是标记要删除的行。
http://msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx
答案 4 :(得分:4)
可能是我的答案不再有用。 使用DataRow的Foreach中的异常抛出仅出现在.Net 2.0及更早版本中,原因在于msdn中的描述 http://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx
如果该行的RowState已添加,则该行将从表中删除。
使用Delete方法后,RowState变为Deleted。在您调用AcceptChanges之前,它仍会被删除。
通过调用RejectChanges可以取消删除已删除的行。
要传递此问题,您可以在使用foreach之前调用DataTable.AcceptChanges()
答案 5 :(得分:2)
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
请参阅快照以了解其工作情况。
我希望现在能解决这个问题。
答案 6 :(得分:1)
如果删除一行,则在迭代时Rows
内容会发生更改,这会导致迭代无效。
但是,您可以先将行复制到集合中,然后遍历集合并删除那些行。这可以确保通过更改要迭代的数据来中断迭代。
答案 7 :(得分:1)
通过使用List映射要删除的行然后删除DataTable迭代之外的行来实现此目的的最简单方法。
C#
List<DataRow> rowsWantToDelete= new List<DataRow>();
foreach (DataRow dr in dt.Rows)
{
if(/*Your condition*/)
{
rowsWantToDelete.Add(dr);
}
}
foreach(DataRow dr in rowsWantToDelete)
{
dt.Rows.Remove(dr);
}
VB
Dim rowsWantToDelete As New List(Of DataRow)
For Each dr As DataRow In dt
If 'Your condition' Then
rowsWantToDelete .Add(dr)
End If
Next
For Each dr As DataRow In rowsWantToDelete
dt.Rows.Remove(dr)
Next
答案 8 :(得分:1)
还有其他版本(我认为更容易)我刚才使用的内容:
int i=0;
while (i < myDataTable.Rows.Count)
{
if (condition) //should it be deleted?
myDataTable.Rows.RemoveAt(i);
else
i++;
}
这更快。
答案 9 :(得分:1)
仅适用于寻找像我这样的特定场景的人 我需要缩短所花费的时间,一旦从每一行中提取了一些有用的信息,我就通过标记为已删除来排除该行。
希望这有助于某人...
foreach (DataRow dataRow in dataTable.Rows)
{
if (dataRow.RowState != DataRowState.Deleted)
{
if (your condition here)
{
dataRow.Delete();
}
}
}
答案 10 :(得分:0)
这几乎适用于任何收藏品。如果您在循环浏览集合时尝试删除项目,则会出现问题。例如,如果删除第3行,则前一行#4将成为第3行。
答案 11 :(得分:0)
使用此:
for (int i = 0; i < myDataTable.Rows.Count; i++)
{
myDataTable[i].Delete();
}
答案 12 :(得分:0)
如果项目有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;
}
请注意,对象具有.GetXXXX()
集合,例如FileInfo
(IIRC),
删除foreach
中的项目内容是可以接受的。我考虑过的一个解决方案是创建一个提供.GetItems()
方法的扩展方法。
答案 13 :(得分:0)
这是因为它看起来像是要拆卸您攀爬的楼梯的楼梯。简单地说,您无法删除迭代的项目。
因此,您应该使用不同的数组来迭代并从数据表Rows
属性中删除它们。
foreach (DataRow dataRow in dataTable.Select())
{
if (true)
{
dataTable.Rows.Remove(dataRow);
}
}
答案 14 :(得分:0)
Sure Magents
我就是这样做的,并且工作正常
dt = GetStationeryConsolidationDetails(txtRefNo.Text);
int intRows = dt.Rows.Count;
int x = 0;
for (int c = 0; c < intRows; c++)
{
if (dt.Rows[c - x]["DQTY"].ToString() == "0")
{
dt.Rows[c - x].Delete();
dt.AcceptChanges();
x++;
}
}