从DataTable中删除特定的行
我想从DataTable中删除一些行,但是会出现这样的错误,
collections被修改; 枚举操作可能不会执行
我用于删除这段代码,
foreach(DataRow dr in dtPerson.Rows){ if(dr["name"].ToString()=="Joe") dr.Delete(); }
那么,这个问题是怎么解决的呢? 你build议哪种方法?
如果您从集合中删除某个项目,则该集合已被更改,您无法继续通过该项目进行枚举。
相反,使用For循环,例如:
for(int i = dtPerson.Rows.Count-1; i >= 0; i--) { DataRow dr = dtPerson.Rows[i]; if (dr["name"] == "Joe") dr.Delete(); }
请注意,您正在反向迭代,以避免在删除当前索引后跳过一行。
在每个人都跳到' 你不能删除Enumeration '行列的行之前,你需要首先意识到DataTables是事务性的 ,在你调用AcceptChanges()之前不会在技术上清除更改,
如果您在调用Delete时看到此exception,那么您已经处于未决更改数据状态 。 例如,如果你刚刚从数据库加载,调用Delete将抛出一个exception,如果你在一个foreach循环。
但! 但!
如果从数据库加载行并调用函数“ AcceptChanges() ”,则将所有这些待处理的更改提交给DataTable。 现在,您可以遍历调用Delete()的行的列表,而不必考虑世界上的情况,因为它只是在删除行上标记行,但在您再次调用AcceptChanges()
我意识到这个答复有点过时,但最近我不得不面对一个类似的问题,希望这为将来的开发人员工作10年的代码节省了一些痛苦:)
Ps这是一个由Jeff添加的简单代码示例:
C# YourDataTable.AcceptChanges(); foreach (DataRow row in YourDataTable.Rows) { // If this row is offensive then row.Delete(); } YourDataTable.AcceptChanges(); VB.Net ds.Tables(0).AcceptChanges() For Each row In ds.Tables(0).Rows ds.Tables(0).Rows(counter).Delete() counter += 1 Next ds.Tables(0).AcceptChanges()
用这个解决scheme:
for(int i = dtPerson.Rows.Count-1; i >= 0; i--) { DataRow dr = dtPerson.Rows[i]; if (dr["name"] == "Joe") dr.Delete(); }
如果在删除行之后要使用该数据表,将会出现错误。 所以你可以做的是:replacedr.Delete();
与dtPerson.Rows.Remove(dr);
这对我有用,
List<string> lstRemoveColumns = new List<string>() { "ColValue1", "ColVal2", "ColValue3", "ColValue4" }; List<DataRow> rowsToDelete = new List<DataRow>(); foreach (DataRow row in dt.Rows) { if (lstRemoveColumns.Contains(row["ColumnName"].ToString())) { rowsToDelete.Add(row); } } foreach (DataRow row in rowsToDelete) { dt.Rows.Remove(row); } dt.AcceptChanges();
DataRow[] dtr=dtPerson.select("name=Joe"); foreach(var drow in dtr) { drow.delete(); } dtperson.AcceptChanges();
我希望这会帮助你
或者只是将一个DataTable 行集合转换成一个列表:
foreach(DataRow dr in dtPerson.Rows.ToList()) { if(dr["name"].ToString()=="Joe") dr.Delete(); }
要从DataTable中删除整行 ,请这样做
DataTable dt = new DataTable(); //User DataTable DataRow[] rows; rows = dt.Select("UserName = 'KarthiK'"); //'UserName' is ColumnName foreach (DataRow row in rows) dt.Rows.Remove(row);
<asp:GridView ID="grd_item_list" runat="server" AutoGenerateColumns="false" Width="100%" CssClass="table table-bordered table-hover" OnRowCommand="grd_item_list_RowCommand"> <Columns> <asp:TemplateField HeaderText="No"> <ItemTemplate> <%# Container.DataItemIndex + 1 %> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Actions"> <ItemTemplate> <asp:Button ID="remove_itemIndex" OnClientClick="if(confirm('Are You Sure to delete?')==true){ return true;} else{ return false;}" runat="server" class="btn btn-primary" Text="REMOVE" CommandName="REMOVE_ITEM" CommandArgument='<%# Container.DataItemIndex+1 %>' /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> **This is the row binding event** protected void grd_item_list_RowCommand(object sender, GridViewCommandEventArgs e) { item_list_bind_structure(); if (ViewState["item_list"] != null) dt = (DataTable)ViewState["item_list"]; if (e.CommandName == "REMOVE_ITEM") { var RowNum = Convert.ToInt32(e.CommandArgument.ToString()) - 1; DataRow dr = dt.Rows[RowNum]; dr.Delete(); } grd_item_list.DataSource = dt; grd_item_list.DataBind(); }
我知道这是非常古老的问题,我前几天也有类似的情况。
问题是,在我的桌子是约。 10000行,所以循环低谷的DataTable
行非常慢。
最后,我发现更快的解决scheme,在那里我复制源DataTable
与所需的结果,清除源DataTable
和merge
结果从临时DataTable
到源之一。
注意 :改为在DataRow
search名为Joe
name
您必须search所有不具有名称Joe
logging(与search的方式相反)
有例子( vb.net
):
'Copy all rows into tmpTable whose not contain Joe in name DataRow Dim tmpTable As DataTable = drPerson.Select("name<>'Joe'").CopyToTable 'Clear source DataTable, in Your case dtPerson dtPerson.Clear() 'merge tmpTable into dtPerson (rows whose name not contain Joe) dtPerson.Merge(tmpTable) tmpTable = Nothing
我希望这个较短的解决scheme将有助于某人。
有c#
代码(不知道是否正确,因为我使用在线转换器:():
//Copy all rows into tmpTable whose not contain Joe in name DataRow DataTable tmpTable = drPerson.Select("name<>'Joe'").CopyToTable; //Clear source DataTable, in Your case dtPerson dtPerson.Clear(); //merge tmpTable into dtPerson (rows whose name not contain Joe) dtPerson.Merge(tmpTable); tmpTable = null;
当然,如果没有结果(例如,如果你的dtPerson
不包含name
Joe
,它将抛出exception),我使用了Try/Catch
,所以你对你的表不做任何处理。
问题在哪里:禁止从foreach循环中的集合中删除项目。
解决scheme:或者像Widor写的那样,或者使用两个循环。 在DataTable的第一遍中,只存储(在临时列表中)对要删除的行的引用。 然后在第二遍你的临时列表中删除这些行。
我有一个数据集在我的应用程序,我去设置更改(删除行),但ds.tabales["TableName"]
是只读的。 然后我发现这个解决scheme。
这是一个WPF的C#
应用程序,
try { var results = from row in ds.Tables["TableName"].AsEnumerable() where row.Field<string>("Personalid") == "47" select row; foreach (DataRow row in results) { ds.Tables["TableName"].Rows.Remove(row); } }