比较两个数据表并删除重复项(无联接)

时间:2019-01-14 07:33:37

标签: c# linq duplicates

我需要比较两个数据表,删除重复数据,然后填充表格视图。

这是我到目前为止尝试过的

DataTable cols = new DataTable();
DataTable cols2 = new DataTable();
DataTable cols3 = cols.Copy();

foreach(DataRow row1 in cols2.Rows) 
{
 bool isRecordExist = false;
 foreach(DataRow row2 in cols.Rows) 
 {
  if (row1 == row2) 
  {
   isRecordExist = true;
  }

  if (!isRecordExist) 
  {
   cols3.ImportRow(row1);
  }
 }
}

dgvfcolumns.DataSource = cols3;

但不是删除重复项,而是将第二个数据表(cols2)中的行添加到第一个数据表(cols)。

有什么主意吗? 我还想问我是否必须将数据表转换为数组? 谢谢

修改 我用这样的组合填充我的第一个数据表...  Obtaining combinations of k elements from n in C#

第二个数据表具有表中的值,我用选择填充它

SqlDataAdapter sqlDa = new SqlDataAdapter("select concat(N1, ' ', N2, ' ',N3, ' ',N4, ' ',N5) FROM Cols2", sqlCon);

2 个答案:

答案 0 :(得分:1)

这是自定义[MCVE]。表1和表2都有唯一和重复的行。

DataTable dataFromSourceA = new DataTable();    
DataTable dataFromSrouceB = new DataTable();

dataFromSourceA.Columns.Add("DataFromSourceA", typeof(string));
dataFromSrouceB.Columns.Add("DataFromSrouceB", typeof(string));

dataFromSourceA.Rows.Add("1,2,3,4,5"); // Dupe                
dataFromSourceA.Rows.Add("2,2");
dataFromSourceA.Rows.Add("4,5,6,7,8");

dataFromSourceB.Rows.Add("1,2,3,4,5"); // Dupe
dataFromSourceB.Rows.Add("2,2,2");
dataFromSourceB.Rows.Add("42");

使用.AsEnumerable()之后,您可以简单地使用LinQ查询那些Datable。
T1中的行与T2中的任何行都匹配。

// List of Duplicate
var dupes =
   dataTable1
       .AsEnumerable()
       .Where(r1 =>
            dataTable2
               .AsEnumerable()
               .Any(r2 =>
                   {
                       var c1 = r1.Field<string>(0);
                       var c2 = r2.Field<string>(0);

                       var splitC1 = c1.Split(',').Select(x => x.Trim()).ToList();
                       var splitC2 = c2.Split(',').Select(x => x.Trim()).ToList();

                       return true
                              && (splitC1.Count() == splitC2.Count())
                              && !splitC1.Except(splitC2).Any();
                   }
                )
        );

答案 1 :(得分:0)

您可以结合使用Except和Union功能,并使用默认的DataRowComparer:

    // create the 2 datatables - must have the same schema
    DataTable  dataTable1 = new DataTable();
    dataTable1.Columns.Add(new DataColumn("Id"));
    dataTable1.Columns.Add(new DataColumn("FirstName"));
    dataTable1.Columns.Add(new DataColumn("LastName"));

    DataTable  dataTable2 = dataTable1.Clone(); 

    dataTable1.Rows.Add(new object[] {1, "John", "Doe"}); 
    dataTable1.Rows.Add(new object[] {2, "Peter", "Rabbit"});

    dataTable2.Rows.Add(new object[] {1, "John", "Doe"});
    dataTable2.Rows.Add(new object[] {2, "Peter", "Smith"});

    DataTable resultsTable = dataTable1.Clone();  // table to keep results

    // this will copy all distinct rows into the resultsTable 
    dataTable1.AsEnumerable()
            .Union(dataTable2.AsEnumerable().Except(dataTable1.AsEnumerable(), DataRowComparer.Default))   // all rows in table2 that do not exists in table1
        .ToList()   
        .ForEach(r => resultsTable.ImportRow(r));  // import the distinct rows into the resultsTable.

    DataTable resultsTable2 = dataTable1.Clone();
    // this will copy only the rows that DO NOT exist in both tables into the resultsTable2 (effectively deletes duplicate rows from both tables)
    dataTable1.AsEnumerable().Except(dataTable2.AsEnumerable(), DataRowComparer.Default)
            .Union(dataTable2.AsEnumerable().Except(dataTable1.AsEnumerable(), DataRowComparer.Default))   // all rows in table2 that do not exists in table1
        .ToList()   
        .ForEach(r => resultsTable2.ImportRow(r));  // import the distinct rows into the resultsTable.