NoS*_*ler 3 c# datatable dataset winforms
我在DataSet中有一个带有列C1(PK),C2和C3(唯一值)的DataTable dt1,删除了一些行后,我将进行AcceptChanges.我有另一个DataTable dt2,其结构与dtA相同.我想删除dtA中存在于dtB中的行,比较C3(唯一值)并执行AcceptChanges.
我可以达到非常接近,但不是我想做的事情,除了下面(从这里学到):
var a = dt1.AsEnumerable().Select(r => r.Field<Guid>("C3"));
var b = dt2.AsEnumerable().Select(r => r.Field<Guid>("C3"));
var c = a.Except(b);
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是,我只得到属于C3列的值列表.我可以做多一些,如图这里,但话又说回来,我将有一个新的DataTable,我不会还是改变现有的DT1表.
我想到的第二种方法是做如下的事情:
foreach (DataRow r1 in ds1.Tables[0].Rows)
{
foreach(DataRow r2 in dt2.Rows)
{
if (r1.Field<Guid>("Guid1") == r2.Field<Guid>("Guid2"))
{
r1.Delete();
}
}
}
Run Code Online (Sandbox Code Playgroud)
删除行后,我收到错误消息"此行已从表中删除,并且没有任何数据." 我在这里错过了什么?
我也有一种感觉,可能有更好的方法这样做,只是不知道大声笑.
我收到一条错误消息"此行已从表中删除但没有任何数据'我在这里缺少什么?
你有两个循环 - 外部和内部.你有两个问题.第一个是找到匹配时删除行.在内循环的下一次迭代中,您试图获取已删除行的值,这会抛出异常.但是即使你在删除行后会破坏内部循环,你也会遇到另一个问题 - 修改你要枚举的行.所以,你的代码应如下所示:
foreach (DataRow r1 in dt1.Rows.Cast<DataRow>().ToArray()) // save rows to array
{
foreach (DataRow r2 in dt2.Rows)
{
if (r1.Field<Guid>("C3") == r2.Field<Guid>("C3"))
{
r1.Delete();
break; // break inner loop
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我会使用LINQ方法 - 通过连接id字段上的行来获取要删除的行,然后从表中删除它们:
var rowsToDelete = from r1 in dt1.AsEnumerable()
join r2 in dt2.AsEnumerable()
on r1.Field<Guid>("C3") equals r2.Field<Guid>("C3")
select r1;
foreach(DataRow row in rowsToDelete.ToArray())
row.Delete(); // marks row as deleted;
Run Code Online (Sandbox Code Playgroud)
注意:在Delete
现有DataRow上使用方法后,其RowState将变为已删除.行仍然被删除,直到您调用AcceptChanges
,从表中删除行.
归档时间: |
|
查看次数: |
10179 次 |
最近记录: |