有两个结构完全一样的datatable,怎么才能比较出来哪些行的数据不一样?(在线等待)

解决方案 »

  1.   

    DataTable设定关键字了吗?
    如果设定了,先按照关键字排序,然后再依次比较。
      

  2.   

    我在网上看到了2种办法
    1。merge.然后再根据datarow的状态,取得变化。
    2。两个datatable分别遍历还有人说两个datatable建立关联。
    第二个办法虽然很保险,但是有点迟钝。
    第一个办法不知道保险不保险
    第三个办法不会用。
    正规的办法是哪个?
      

  3.   

    1。merge.然后再根据datarow的状态,取得变化。
    merge只能是DATASET吧,DATATABLE可以merge?
    不过merge倒是个方法,但是表必须要有关键字。。要不没发判断数据是否一样。。
    没有关键字,merge的话之是在把2个表叠加而已
      

  4.   

    条件:若每个表的数据都按主键排序则可:双重循环遍历比对,比对时有个算法优化,即第二个表的循环开始条件并非每次都从0开始,而是从上次已走到的地方继续往下走我写过这样的方法,贴出来给你看看吧
            /// <summary>
            /// 此方法比对数据提供方的源数据表与数据申请方的关键数据表,并将三种结果(insert,update,delete)序列化为字节流返回
            /// </summary>
            /// <param name="dtSource">源数据表</param>
            /// <param name="dtClientKey">关键数据表</param>
            /// <param name="crType">比对的类型</param>
            /// <returns>比对结果的字节流</returns>
            public MemoryStream GetSYNCCompareResultStream(DataTable dtSource, DataTable dtClientKey, CompareResultType crType)
            {
                //if (dtSource.TableName != dtClientKey.TableName) { throw new Exception("不同的表请不要拿来比对!"); }
                //表结构信息以本地表名为准
                ColumnsInfoTable cit = GetSYNCDataTableInfo(dtSource.TableName);            MemoryStream ms = new MemoryStream();
                RawSerializer rs = new RawSerializer(ms);
                //返回的表名以客户表名为准
                rs.Serialize(dtClientKey.TableName);
                //记录需要Insert的新数据
                List<int> listInsert = new List<int>();
                //记录需要Update的新数据及哪些列需要Update
                DataTable dtUpdate = InitDataTableForUpdate(cit);
                //记录需要Delete的行的PrimaryKey值项
                bool[] isNeedDeleteRows = null;            if (dtSource.Rows.Count > 0 && dtClientKey.Rows.Count > 0)
                {
                    int nNeedDeleteCount = dtClientKey.Rows.Count;
                    isNeedDeleteRows = new bool[dtClientKey.Rows.Count];
                    for (int i = 0; i < isNeedDeleteRows.Length; i++)
                    {
                        isNeedDeleteRows[i] = true;
                    }                #region 比对两个表的一般逻辑                //比对两个表的逻辑开始
                    bool bFound = false;
                    bool bFit = false;
                    int nFitIndex = -1;
                    DataRow drUpdate = null;
                    for (int i = 0; i < dtSource.Rows.Count; i++)
                    {
                        bFound = false;
                        //注意:因为两个表都是按照Key项递增查询的,此循环才可以优化
                        for (int j = nFitIndex + 1; j < dtClientKey.Rows.Count; j++)
                        {
                            //判断Key列的值是否相等
                            bFit = true;
                            foreach (int n in cit.KeyColumns)
                            {
                                if (dtSource.Rows[i][n].Equals(dtClientKey.Rows[j][n]) == false)
                                {
                                    bFit = false;
                                    break;
                                }
                            }                        if (bFit == true)
                            {
                                nFitIndex = j;
                                bFound = true;
                                //如果dt2中的数据能与dt1中的匹配上,则不须删除
                                isNeedDeleteRows[j] = false;
                                nNeedDeleteCount--;
                                //判断是否需要Update,如果需要,则把相应的值填入dtUpdate中
                                int nColumns = cit.Rows.Count;
                                bool isRowNeedUpdate = false;
                                if (drUpdate == null) { drUpdate = dtUpdate.NewRow(); }                            int n;
                                for (int k = 0; k < cit.SmallItemColumns.Length; k++)
                                {
                                    n = cit.SmallItemColumns[k];
                                    if (dtSource.Rows[i][n].Equals(dtClientKey.Rows[j][n]) == true)
                                    {
                                        drUpdate[n] = DBNull.Value;
                                        drUpdate[nColumns + n] = false;
                                    }
                                    else
                                    {
                                        isRowNeedUpdate = true;
                                        drUpdate[n] = dtSource.Rows[i][n];
                                        drUpdate[nColumns + n] = true;
                                    }
                                }                            if (cit.BLOBColumns != null && cit.BLOBColumns.Length > 0)
                                {
                                    for (int k = 0; k < cit.BLOBColumns.Length; k++)
                                    {
                                        n = cit.BLOBColumns[k];                                    //比对的是BLOB的MD5列
                                        if (dtSource.Rows[i][nColumns + k].Equals(dtClientKey.Rows[j][nColumns + k]) == true)
                                        {
                                            drUpdate[n] = DBNull.Value;
                                            drUpdate[nColumns + n] = false;
                                        }
                                        else
                                        {
                                            isRowNeedUpdate = true;
                                            drUpdate[n] = dtSource.Rows[i][n];
                                            drUpdate[nColumns + n] = true;
                                        }
                                    }
                                }                            if (isRowNeedUpdate == true)
                                {
                                    foreach (int row in cit.KeyColumns)
                                    {
                                        drUpdate[row] = dtClientKey.Rows[j][row];
                                        drUpdate[row + nColumns] = false;
                                    }
                                    dtUpdate.Rows.Add(drUpdate);
                                    drUpdate = null;
                                }
                                break;
                            }
                        }
                        //未找到匹配项,说明此值需要新增
                        if (bFound == false)
                        {
                            listInsert.Add(i);
                        }
                    }
                    #endregion                //比对的一般逻辑结束,开始序列化                #region 将比对结果序列化为字节流
                    //省略
                  #endregion
                }
                #region 特殊情况的处理,全空,全删,全增
                else if (dtSource.Rows.Count == 0 && dtClientKey.Rows.Count == 0)
                {
                    //无需任何改变,两个都是空表
                }
              else if (dtSource.Rows.Count == 0)
                {
                    //全部需要删除,其他两项无需更改
                }
              else
                {
                    //全部需要新增,其他两项无需更改
                }
                #endregion            return ms;
            }
      

  5.   

    有两个结构完全一样的datatable,怎么才能比较出来哪些行的数据不一样
    你的问题还需要你给解释一下:怎么才算是"数据不一样",是任何A记录!=B记录的都算?还是主键相同而其它列不同的算数据不一样呢?
    (列a为主键)
    A
    a, b, c
    B
    a, b, c
    如果是前者
    只能循环遍历了如果是后者
    select A.a, A.b, A.c
    from A,B
    where (A.a = B.a) and (A.b != B.b or A.c != b.c)
    B表的查询也一样
      

  6.   

    DataTable A, B;
    int rows = A.Rows.Count;
    int cols = A.Columns.Count;
    for(int i=0; i< rows; i++)
    {
        for (int j=0; j< cols; j++)
        {
            if (A.Rows[i][j].ToString() != B.Rows[i][j])
            { 
                 //
                 break;
             }
         }
    }
      

  7.   

    既然两个表结构一下,那么通过DataTable.Merge方法然后再根据datarow的状态,取得变化应该是很好的一种方式。