【问题标题】:Remove rows from a DataTable where an entry exist in another DataTable从另一个 DataTable 中存在条目的 DataTable 中删除行
【发布时间】:2011-11-03 15:55:30
【问题描述】:

对不起,令人困惑的主题行:)

我想用我的 DataTable:s 进行类似 SQL 的查询:我想做这样的事情

// Is named "BadValues" Rows contain: id1, id2
DataTable tableReadFromFile = readFromFile();
// Is named "AllValues" Rows contain id1, id2
DataTable tableReadFromSql = readFromSql

DataTable resultTable = 
    tableReadFromFile.select("where AllValues.id1 not in (select id1 from BadValues) and AllValues.id2 not in (select id2 from BadValues)");

如果我的“BadValues”表如下所示:

id1 id2
0    1
10   11
20   21

我的“AllValues”表如下所示:

id1 id2
0   1
0   2
1   1
10  11
10  12
12  11
20  21
20  22
22  21

我希望结果表看起来像这样:

id1 id2
0   2
1   1
10  12
12  11
20  22
22  21

换句话说:如果对 id1,id2 存在于表“BadValues”和“AllValues”中,我想删除它们,以便它们不存在于结果表中。

如果 SQL 数据库中存在“BadValues”表,这在 SQL 中会相当简单,但因为它是从文件中加载的,这是不可能的。

就像现在一样,我遍历“BadValues”中的所有行,并使用设置的 id1 和 id2 值构造单独的 SQL 查询。由于我有很多数据,这非常耗时。

感谢任何提示!

【问题讨论】:

    标签: c# sql select datatable dataset


    【解决方案1】:

    我认为这样做可以:

    DataTable tblBadValues; // filled however
    DataTable tblAllValues; // filled however
    tblBadValues.Merge(tblAllValues); // this will add to tblBadValues all records 
                                      // that aren't already in there
    DataTable tblResults = tblBadValues.getChanges(); // this will get the records
        // that were just added by the merge, meaning it will return all the records
        // that were originally in tblAllValues that weren't also in tblBadValues
    tblBadValues.RejectChanges(); // in case you need to re-use tblBadValues
    

    【讨论】:

    • 感谢您的回复!我试过了,但我必须为它设置主键: DataColumn[] badValuesKeys = new DataColumn[2]; badValuesKeys[0] = badValues.Columns["id1"]; badValuesKeys[1] = badValues.Columns["id2"]; badValues.PrimaryKey = badValuesKeys;我还是有问题。 badValues.GetChanges() 返回整个合并表。我在合并之前尝试调用 badValues.AcceptChanges() 但没有运气。
    【解决方案2】:

    使用Linq to dataset:

    var badValues = new HashSet<Tuple<int, int>>(
                      tableReadFromFile.AsEnumerable().
                                        Select(row => 
                                          new Tuple<int, int>(row.Field<int>("id1"), row.Field<int>("id2"))));
    
    var result = tableReadFromSql.AsEnumerable().
                                        Where(row => !(badValues.Contains(
                                        new Tuple<int, int>(row.Field<int>("id1"), row.Field<int>("id2")))));
    

    第一条语句基本上创建了代表错误值的元组的哈希集。

    第二个在第二个表中搜索id不在哈希集中的行。

    【讨论】:

      【解决方案3】:

      我有一个想法,尽管您必须执行 LINQ to SQL。

      var query = from data in AllObjects                                    
                          select data;
      
      foreach (DataObject o in BadData)
      {
          DataObject temp = o;
          query = query.Where(x => !((x.id1 == temp.id1) && (x.id2 == temp.id2)));
      }
      //query now contains the expression to get only good rows.
      

      只有当query 被迭代(或.ToArray 等)时,它才会调用您的数据库服务器。

      【讨论】:

        猜你喜欢
        • 2013-11-09
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 2016-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多