如何在tbl1中查找不在tbl2中的行并将其删除
本文关键字:删除 tbl1 查找 tbl2 | 更新日期: 2023-09-27 18:24:57
我是VS C#的初学者,正在处理我继承的WINFORM项目。我需要在tbl1中查找tbl2中不存在的行并将其删除。连接列为:tbl1===>"VistaFieldName"tbl2===>"FMFieldName"
我在StackOverflow链接中发现了一些代码,使用LINQ获取一个DataTable中存在的内容,但另一个DataTable中没有。我认为这可能可行,但它使用的是LINQ,我不熟悉LINQ。
编辑:尝试了链接中的查询语法,它成功了,但现在我遇到了一个异常。如果我在第一个foreach循环中接受更改,我会得到"collection modified",如果我将接受更改放在foreach循环之外,我会收到一个异常"can't access rows marked for delete"
我能做些什么来防止这种情况发生?
else if (dsVX130.Tables["tAttributes"].Rows.Count > 0)
{
var rowsOnlyIntblsAttributes = from r in tblsAttributes.AsEnumerable() //was dt1
//make sure there aren't any matching names in dt2
where !tbltAttributes.AsEnumerable().Any(r2 => r["VistaFieldNumber"].ToString().Trim().ToLower() == r2["FMFieldNumber"].ToString().Trim().ToLower())
select r;
DataTable result = rowsOnlyIntblsAttributes.CopyToDataTable();
//result.Rows[0]["VistaFieldNumber"]
string vresult;
foreach (DataRow dr in result.Rows)
{
vresult=result.Rows[0]["VistaFieldNumber"].ToString();
foreach (DataRow dr1 in tblsAttributes.Rows)
{
if (dr1["VistaFieldNumber"].ToString() == vresult)
{
dr1.Delete();
tblsAttributes.AcceptChanges();
}
}
}
tblsAttributes.AcceptChanges();
applyAttributes();
解决:我使用了Getwhat中的查询语法示例,使用LINQ在tbl1中而不是tbl2中查找行,然后发出了删除行。起初我使用FOREACH,但发现不能同时枚举表和删除行。这是通过将FOREACH替换为FOR来解决的,如图所示。
在测试最终结果时,我发现我需要测试查询结果中返回的行,否则在发布复制表时我会收到异常。我使用的测试是
else if (dsVX130.Tables["tAttributes"].Rows.Count > 0)
{
var rowsOnlyIntblsAttributes = from r in tblsAttributes.AsEnumerable() //was dt1
//make sure there aren't any matching names in dt2
where !tbltAttributes.AsEnumerable().Any(r2 => r["VistaFieldNumber"].ToString().Trim().ToLower() == r2["FMFieldNumber"].ToString().Trim().ToLower())
select r;
if (rowsOnlyIntblsAttributes.Any())
{
DataTable result = rowsOnlyIntblsAttributes.CopyToDataTable();
//result.Rows[0]["VistaFieldNumber"]
string vresult;
for (int i = 0; i < result.Rows.Count; i++)
//foreach (DataRow dr in result.Rows)
{
//var tempRow = result.Rows[i];
//var temp = result.Rows[i][0];
vresult=result.Rows[i]["VistaFieldNumber"].ToString();
for (int j = 0; j < tblsAttributes.Rows.Count; j++)
//foreach (DataRow dr1 in tblsAttributes.Rows)
{
DataRow dr1 = tblsAttributes.Rows[j];
if (dr1["VistaFieldNumber"].ToString() == vresult)
{
dr1.Delete();
tblsAttributes.AcceptChanges();
break;
}
//tblsAttributes.AcceptChanges();
}
}
}
//tblsAttributes.AcceptChanges();
applyAttributes();