1

我想在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() };
}

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

4

3 回答 3

2

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

如果 DataRow 不起作用,我建议将相关记录转换为字符串,将它们连接起来,然后将它们放入 HashSet。在插入行之前,请检查 HashSet 是否已经包含它(使用 Contains)。如果是这样,则您找到了重复项。

编辑:

这种方法是 O(n)。

于 2009-03-20T14:27:44.073 回答
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))
      }
   }
}
于 2009-03-19T21:56:32.130 回答
0

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

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

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

于 2009-03-20T14:23:10.293 回答