0

我有两个数据表 dt1 和 dt2,我需要遍历它们并将 dt1 的两列与 dt2 的相同两列进行比较。我是 Linq 的初学者,但不确定使用 Linq 会更快吗?

每个 DataTable 有 4500 多行和 514 列数据,所以这是我们在这里处理的大型数据集。

列位置“0”具有两个数据表中每一行的唯一 ID。我正在尝试比较列位置“6”中的数据,并将列位置“7”中的数据值从一个数据表与另一个数据表进行比较。

我的代码需要大约 10-15 分钟来处理。

将一个 DataTable 中的两列与另一列进行比较的最佳和更快的解决方案是什么?

这是我的代码

 public void CompareDataTables(DataTable dt1, DataTable dt2)
 {

     foreach (DataRow row1 in dt1.Rows)
        {
            foreach (DataRow row2 in dt2.Rows)
            {
                var array1 = row1.ItemArray;
                var array2 = row2.ItemArray;

                if(row1[0].ToString() == row2[0].ToString())
                {

                    if (row1[6].ToString() != row2[6].ToString())
                    {
                        tbCPDEResults.Text += "Project ID: " + row1[0] + " has a change in INV Approval Status. \nOld Value: " + row1[6] + " \nNew Value: " + row2[6] + "\n";
                    }


                    if (row1[7].ToString() != row2[7].ToString())
                    {
                        tbCPDEResults.Text += "Project ID: " + row1[0] + " has a change in INV Progress. \nOld Value: " + row1[7] + " \nNew Value: " + row2[7] + "\n";
                    }

                }

             }//inner foreach
          }//outter foreach

}

4

2 回答 2

0

我个人讨厌数据表,这是一个最好通过在数据库级别运行单独查询来解决的问题,无论如何,如果您坚持应用程序本身的数据表解决方案,这会更加优化:

  public static void CompareDataTables(DataTable dt1, DataTable dt2) {
    var builder = new StringBuilder(10000);

    var rows = new Dictionary<string, List<DataRow>>(dt1.Rows.Count * 3);
    foreach (DataRow row in dt1.Rows) {
      string key = row[0].ToString();
      List<DataRow> rowSet;
      if (!rows.TryGetValue(key, out rowSet)) {
        rowSet = new List<DataRow> { row };
        rows.Add(key, rowSet);
      } else {
        rowSet.Add(row);
      }
    }

    foreach (DataRow row2 in dt2.Rows) {
      List<DataRow> rowSet;
      if (rows.TryGetValue(row2[0].ToString(), out rowSet)) {
        foreach (var row1 in rowSet) {
          if (row1[6].ToString() != row2[6].ToString()) {
            builder.AppendFormat("Project ID: {0} has a change in INV Approval Status. \nOld Value: {1} \nNew Value: {2}\n", row1[0], row1[6], row2[6]);
          }
          if (row1[7].ToString() != row2[7].ToString()) {
            builder.AppendFormat("Project ID: {0} has a change in INV Progress. \nOld Value: {1} \nNew Value: {2}\n", row1[0], row1[7], row2[7]);
          }
        }
      }
    }
    tbCPDEResults.Text = builder.ToString();
  }
于 2013-06-12T15:40:11.513 回答
0

在 RDMS 中,这称为“嵌套循环连接”,通常效率最低(尽管您可能别无选择)。

幸运的是,这听起来像你 - 你可以做一个“合并加入”。基本上,您按两个表的共享唯一标识符对它们进行排序,然后一次扫描两个表。

    int  rowIndex1 = 0;
    int  rowIndex2 = 0;
    while (rowIndex1 < table1.Rows.Count && rowIndex2 < table2.Rows.Count)
        {
        DataRow  row1 = table1.Rows[rowIndex1];
        DataRow  row2 = table2.Rows[rowIndex2];

        int  pk1 = Int32.Parse((string)row1[0]);
        int  pk2 = Int32.Parse((string)row2[0]);

        if (pk1 == pk2)
            {
            string  field1A = (string)row1[6];
            string  field2A = (string)row2[6];
            if (field1A != field2A)  Console.WriteLine("Field A differs for record #{0}: table 1 is {1}, tables 2 is {2}.", pk1, field1A, field2A);

            string  field1B = (string)row1[7];
            string  field2B = (string)row2[7];
            if (field1B != field2B)  Console.WriteLine("Field B differs for record #{0}: table 1 is {1}, tables 2 is {2}.", pk1, field1B, field2B);

            ++rowIndex1;
            ++rowIndex2;
            }
        else if (pk1 > pk2)
            {
            // There is no record in table 2 with this ID
            ++rowIndex2;
            }
        else if (pk2 > pk1)
            {
            // There is no record in table 1 with this ID
            ++rowIndex1;
            }
        }

顺便说一句,如果您可以将数据导入某种 SQL 服务器,这会容易得多。一个简单的SELECT就可以了。

于 2013-06-12T15:41:38.633 回答