如何在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();

如何在tbl1中查找不在tbl2中的行并将其删除

解决:我使用了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();