比较DataTable中的所有行 - 识别重复记录

时间:2009-03-19 20:55:46

标签: c# .net asp.net linq normalization

我想在没有密钥的情况下对DataTable insertRows中的数据进行规范化。为此,我需要通过查找ID(import_id)来识别和标记重复记录。之后我会只选择不同的。我想到的方法是将每一行与该DataTable insertRows

中的所有行进行比较

DataTable中的列在设计时是未知的,并且没有密钥。在性能方面,该表将具有多达10k到20k的记录和大约40列

如何在不牺牲性能的情况下实现这一目标?

我尝试使用linq,但我不知道如何动态指定where条件 在这里,我将比较每一行的循环中的名字和姓氏

foreach (System.Data.DataRow lrows in importDataTable.Rows)
{
    IEnumerable<System.Data.DataRow> insertRows = importDataTable.Rows.Cast<System.Data.DataRow>();

    var col_matches =
    from irows in insertRows
    where
    String.Compare(irows["fname"].ToString(), lrows["fname"].ToString(), true).Equals(0)
    &&
    String.Compare(irows["last_name"].ToString(), lrows["last_name"].ToString(),true).Equals(0)

    select new { import_id = irows["import_id"].ToString() };
}

foreach (System.Data.DataRow lrows in importDataTable.Rows) { IEnumerable<System.Data.DataRow> insertRows = importDataTable.Rows.Cast<System.Data.DataRow>(); var col_matches = from irows in insertRows where String.Compare(irows["fname"].ToString(), lrows["fname"].ToString(), true).Equals(0) && String.Compare(irows["last_name"].ToString(), lrows["last_name"].ToString(),true).Equals(0) select new { import_id = irows["import_id"].ToString() }; }

欢迎任何想法。 如何使用linq找到类似的列名?&gt;我的类似问题

3 个答案:

答案 0 :(得分:2)

在没有O(n 2 )复杂性的情况下完成此操作的最简单方法是使用有效实现Set操作的数据结构,特别是Contains操作。幸运的是.NET(从3.0开始)包含HashSet对象,它为您执行此操作。为了利用这个,你需要一个在DataTable中封装一行的对象。

如果DataRow不起作用,我建议将相关记录转换为字符串,连接它们然后将它们放在HashSet中。在插入行之前检查HashSet是否已包含它(使用Contains)。如果是,你发现了一个重复。

修改

此方法为O(n)。

答案 1 :(得分:1)

我不确定我是否正确理解了这个问题,但在处理System.Data.DataTable时,以下情况应该有效。

for (Int32 r0 = 0; r0 < dataTable.Rows.Count; r0++)
{
   for (Int32 r1 = r0 + 1; r1 < dataTable.Rows.Count; r1++)
   {
      Boolean rowsEqual = true;

      for (Int32 c = 0; c < dataTable.Columns.Count; c++)
      {
         if (!Object.Equals(dataTable.Rows[r0][c], dataTable.Rows[r1][c])
         {
            rowsEqual = false;
            break;
         }
      }

      if (rowsEqual)
      {
         Console.WriteLine(
            String.Format("Row {0} is a duplicate of row {1}.", r0, r1))
      }
   }
}

答案 2 :(得分:0)

我对LINQ不太了解,但您可以使用.Distinct()运算符吗?

http://blogs.msdn.com/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx

您的问题并不清楚您是否需要专门识别重复的行,或者您是否只是想从查询中删除它们。添加“Distinct”会删除额外的实例,但它不一定会告诉你它们是什么。