【问题标题】:Why won't two Identical DataTables show any differences?为什么两个相同的数据表不会显示任何差异?
【发布时间】:2012-03-29 08:51:03
【问题描述】:

我正在使用DataRelation 比较两个DataTable,并使用此tutorial 返回包含两个原始表不共享的行的第三个表。下面是代码。

public static DataTable Difference(DataTable First, DataTable Second)
{
      //Create Empty Table

      DataTable table = new DataTable("Difference");

      //Must use a Dataset to make use of a DataRelation object

      using(DataSet ds = new DataSet())   
      {
            //Add tables
            ds.Tables.AddRange(new DataTable[]{First.Copy(),Second.Copy()});
            //Get Columns for DataRelation

            DataColumn[] firstcolumns  = new DataColumn[ds.Tables[0].Columns.Count];   
            for(int i = 0; i < firstcolumns.Length; i++)   
            {    
                  firstcolumns[i] = ds.Tables[0].Columns[i];    
            }

            DataColumn[] secondcolumns = new DataColumn[ds.Tables[1].Columns.Count];

            for(int i = 0; i < secondcolumns.Length; i++)    
            {
                  secondcolumns[i] = ds.Tables[1].Columns[i];    
            }    
            //Create DataRelation    
            DataRelation r = new DataRelation(string.Empty,firstcolumns,secondcolumns,false);

            ds.Relations.Add(r);

            //Create columns for return table   
            for(int i = 0; i < First.Columns.Count; i++)    
            {    
                  table.Columns.Add(First.Columns[i].ColumnName, First.Columns[i].DataType);    
            }

            //If First Row not in Second, Add to return table.    
            table.BeginLoadData();

            foreach(DataRow parentrow in ds.Tables[0].Rows)    
            {    
                  DataRow[] childrows = parentrow.GetChildRows(r);

                  if(childrows == null || childrows.Length == 0)    
                        table.LoadDataRow(parentrow.ItemArray,true);        
            }

            table.EndLoadData();    
      }

      return table;    
}

令人惊讶的是,当我练习这段代码时,它只在少数情况下有效,而在其他情况下却失败了。

有一个案例,我正在比较两个相同的表(但来源不同):

  • 相同的列名和DataType
  • 行列数相同
  • 每个单元格中的值相同

只返回一个全新的新表,它实际上与两个原始表具有完全相同的成分

可能错过了什么

是否有可能两个相同的表(我上面提到的共享功能)可以具有其他不同的属性(用户的眼睛似乎看不到)?

或者这可能实际上是一个糟糕的方法?有哪些可能的替代方案?

已编辑

  1. 两个表具有相同的原始数据类型,例如:System.StringSystem.Int32System.DateTime
  2. 这些代码不适用于我测试的所有示例
  3. 这是 1 个样本的打印屏幕(使用 DataSet Visualizer)

【问题讨论】:

  • 这些列的数据类型是什么?它只是原始人吗?也许它们包含一些引用不相等的对象? (...) but has different source (...) 可能是这里的关键。您应该知道,在(例如)var bitmapA = Bitmap.FromFile(@"C:\picture.jpg"); var bitmapB = Bitmap.FromFile(@"C:\picture.jpg"); - bitmapA == bitmapB 之后是 false
  • 理论上该方法应该有效。在预期匹配不起作用的情况下,列的顺序是否相同?你能提供一个不起作用的小例子吗?
  • 明天我会,等我回到办公室=)
  • 问题已编辑。请检查。
  • 我在内存中使用原始数据类型和样本数据创建了相同的 DataTables,并使用了您的方法,结果是一个空的 diff 表。您的列或数据必须有特定的内容。我会尝试限制您在表格中选择的列,看看您是否可以隔离导致问题的特定列。

标签: c# datatable


【解决方案1】:

我曾经写过类似的东西,这是我使用的方法:

首先,这种方法仅适用于每个表中没有重复行的情况。

使用主键..

First.PrimaryKey = firstcolumns;
Second.PrimaryKey = secondcolumns; //These throw exceptions when you have duplicate rows

那么..

foreach (DataRow dr in Second.Rows)
{
    List<Object> l = new List<Object>();

    foreach (DataColumn dc in secondcolumns) l.Add(dr[dc]);

    if (First.Rows.Find(l.ToArray()) == null) //NOT FOUND
    {
        table.Rows.Add(l.ToArray());
    }
}

foreach (DataRow dr in First.Rows)
{
    List<Object> l = new List<Object>();

    foreach (DataColumn dc in firstcolumns) l.Add(dr[dc]);

    if (Second.Rows.Find(l.ToArray()) == null) //NOT FOUND
    {
        table.Rows.Add(l.ToArray());
    }
}

干杯,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2011-06-11
    • 2022-10-08
    • 2020-08-24
    • 1970-01-01
    • 2015-04-06
    相关资源
    最近更新 更多