字段很多
给出点具体的东西!最好是带注释的代码!
    //找出verNew的关键值到verOld中去匹配
    //找不到 该条新增 标记
    //找到并一致 该条未做任何操作 标记
    //找到不一致 该条为修改 标记
    //就版本有未标记的内容 为被删除内容

解决方案 »

  1.   

    的确如此,如果真的是两个结构相同的表,只能逐行比较
    但是如果只是某个表(dtOld)的数据变化了
    而你想获得某些变化,那么请用GetChanges 方法DataTable dtNew = dtOld.GetChanges(DataRowState.Added);
    DataTable dtNew = dtOld.GetChanges(DataRowState.Deleted);
    DataTable dtNew = dtOld.GetChanges(DataRowState.Detached);
    DataTable dtNew = dtOld.GetChanges(DataRowState.Modified);
    DataTable dtNew = dtOld.GetChanges(DataRowState.Unchanged);
      

  2.   

        public DataTable Compare(DataTable verNew, DataTable verOld)
        {
            for (int iRows = 0; iRwos < verOld.Rows.Count; iRows++)
            {
                DataRow[] drs = verNew.Select("verOld.关键字 = " + verOld.Rows[iRows]["verNew.关键字"].ToString());
                if (drs != null)
                {
                    //匹配关键字成功
                    for (int iItems; iItems < drs.Length; iItems++)
                    {
                        //TODO 一个字段一个字段比较罗                }
                }
                else
                {
                    //匹配关键字失败
                    //TODO:为新增标记
                }
            }        //TODO:没有标识就删除
        }
      

  3.   

    我用winform做了个小程序,希望对你有帮助        DataTable oldTable = new DataTable();
            DataTable newTable = new DataTable();
    private void Form1_Load(object sender, EventArgs e)
            {
                oldTable.Columns.Add("Id", typeof(int));
                oldTable.Columns.Add("Name");
                oldTable.Rows.Add("1", "一");
                oldTable.Rows.Add("2", "二");
                
                newTable.Columns.Add("Id", typeof(int));
                newTable.Columns.Add("Name");
                newTable.Rows.Add("1", "一");
                newTable.Rows.Add("2", "三");
                newTable.Rows.Add("3", "二");            MessageBox.Show(dataTableCompare(oldTable, newTable));
            }        private string dataTableCompare(DataTable oldTable, DataTable newTable)
            {
                oldTable.PrimaryKey = new DataColumn[] { oldTable.Columns["Id"], oldTable.Columns["Name"] };
                string ret = string.Empty;
                DataRow dr = oldTable.NewRow();
                for (int i = 0; i < newTable.Rows.Count; i++)
                {
                    dr.ItemArray = newTable.Rows[i].ItemArray;
                    try
                    {
                        oldTable.Rows.Add(dr);
                        
                        //注意:这里Remove以后dr的指针会跑没
                        oldTable.Rows.Remove(dr);
                        //因为前面的Remove使dr的指针跑掉了,所以要重新赋一次值
                        dr.ItemArray = newTable.Rows[i].ItemArray;
                        oldTable.PrimaryKey = new DataColumn[] { oldTable.Columns["Id"] };
                        try
                        {
                            oldTable.Rows.Add(dr);                        ret += string.Format("新表中的第{0}行是新增的\n", i.ToString());
                        }
                        catch
                        {
                            ret += string.Format("新表中的第{0}行是修改过的\n", i.ToString());
                        }
                        finally
                        {
                            oldTable.PrimaryKey = new DataColumn[] { oldTable.Columns["Id"], oldTable.Columns["Name"] };
                        }
                    }
                    catch
                    {
                        ret += string.Format("新表中的第{0}行是没有修改过的\n", i.ToString());
                    }
                }
                return ret;
            }
      

  4.   

    To :cpw999cn 没细看  
    但是 for 里 套try
         try 里套  try
         以catch 获得结果
    等等,太耗费系统资源,如非必要(一般不需要),不要这样做
      

  5.   

    To:heboyi
    删除是判断不出来的,旧表中删除的,新表中有旧表中没有的,对于旧表来说就是新增的,无法判断旧表原来是否有该记录(我想你需要做这种比较就表明你不是直接对旧表的datatable进行操作,否则用不着这样做比较)
      

  6.   

    不好意思,非中文系统,拿写字板写的public DataTable Compare(DataTable dtNew, DataTable dtOld)
        {
            foreach(DataRow dr in dtNew.Rows)
            {
                DataRow[] drs = dtOld.Select("PrimaryKey = " + dr["PrimaryKey"].ToString());
                if (drs != null)  // can match, and there is only one row in drs
                {
                    // compare every column
                    for(int i=0; i<dtNew.columns.count; i++)
                    {
                        drs[0] = dr[i]?
                    }
                    // if all the columns is the same
                    dr["Flag"] = "Unchanged";
                    drs[0]["Flag"] = "Unchanged";
                    
                    // if all the columns is not the same
                    dr["Flag"] = "Modified";
                    drs[0]["Flag"] = "Modified";
                }
                else  // can't match
                {
                    dr["Flag"] = "Added";
                }
            }
            foreach(DataRow dr in dtOld.Rows)
            {
                if (dr["Flag"] = null)  // not (Modified or Added or Unchanged), there is no flag
                {
                    dr["Flag"] = "Delete";
                }
            }
        }以上, 对drs[0]的标记,其实就是对dtOld的相应行的标记
    drs数组并没有开辟新内存,只是对原有数据行的引用
      

  7.   

    已经解决了!
    希望还有更好的方法!到期结贴!给出代码的都有分!
            /// <summary>
            /// 比较两表
            /// </summary>
            /// <param name="oldTable">老的版本</param>
            /// <param name="newTable">新的版本</param>
            /// <param name="primaryKeys">主键</param>
            /// <returns>返回的结果中新增changed列标记结果</returns>
            private static DataTable CompareDataTable(DataTable oldTable, DataTable newTable, params DataColumn[] primaryKeys)
            {
                DataTable result = newTable.Copy();
                DataColumn[] tdc = new DataColumn[oldTable.Columns.Count];
                for (int x = 0; x < oldTable.Columns.Count; x++)
                {
                    tdc[x] = oldTable.Columns[x];
                }
                result.Columns.Add("changed");            oldTable.PrimaryKey = tdc;
                oldTable.Columns.Add("changed");
                DataRow dr = oldTable.NewRow();
                for (int i = 0; i < newTable.Rows.Count; i++)
                {
                    dr.ItemArray = newTable.Rows[i].ItemArray;
                    try
                    {
                        oldTable.Rows.Add(dr);
                        //注意:这里Remove以后dr的指针会跑没
                        oldTable.Rows.Remove(dr);
                        //因为前面的Remove使dr的指针跑掉了,所以要重新赋一次值
                        dr.ItemArray = newTable.Rows[i].ItemArray;
                        oldTable.PrimaryKey = primaryKeys;
                        try
                        {
                            oldTable.Rows.Add(dr);
                            result.Rows[i]["changed"] = "新增";
                        }
                        catch (ConstraintException)
                        {
                            result.Rows[i]["changed"] = "修改";
                            oldTable.Rows[i]["changed"] = "修改";                    }
                        finally
                        {
                            oldTable.PrimaryKey = tdc;
                        }
                    }
                    catch (ConstraintException)
                    {                    result.Rows[i]["changed"] = "没有改变";
                        oldTable.Rows[i]["changed"] = "没有改变";
                    }
                }
                foreach (DataRow rd in oldTable.Rows)
                {
                    if (rd["changed"] == DBNull.Value)
                    {
                        rd["changed"] = "被删除的";
                        DataRow nr = result.NewRow();
                        nr.ItemArray = rd.ItemArray;
                        result.Rows.Add(nr);
                    }
                }
                return result;
            }
      

  8.   

    给LZ说说我以前作的思想:
    首先在OLD和NEW表中分别增加TimeStamp字段,此字段内容由DB负责。
    比较两表时,以NEW表为外循环,依照ID查找OLD表记录,找到再比较TimeStamp字段是否相同同时BREAK此次循环,
    如果找不到则为新增。依次操作即可。
      

  9.   

    To heboyi : 
        你的这种方法请以后不要考虑,try catch 并非是用来做验证的
         比如你要判断一个字符串是否是数字,难道用try catch 来做转换
         转换成功就是数字吗?
         
         到其他地方搜索下try catch 的真正用途吧 
    private void CompareDataTable(DataTable dtOld, DataTable dtNew)
    {
        DataRow[] drS;     //存放指向旧表相应行的指针
        bool bAllTheSame;  //存放某行数据是否有所变更的标志
        foreach(DataRow dr in dtNew.Rows)
        {
            drS = dtOld.Select("ID =" + dr["ID"].ToString());  //检索旧表,看是否有对应行
            if (drS.Length > 0)  //旧表有对应行
            {
                bAllTheSame = true;
                for (int i = 0; i < dtOld.Columns.Count; i++)  //看是否某列的值被变更
                {
                    if (dr[i].ToString().CompareTo(drS[0][i].ToString()) != 0) //有变更
                    {
                        bAllTheSame = false;
                        break;
                    }
                }
                if (bAllTheSame)  //所有列未被变更
                {
                    dr["Status"] = "UnChanged";
                    drS[0]["Status"] = "UnChanged";
                }
                else             //有些列被变更
                {
                    dr["Status"] = "Modified";
                    drS[0]["Status"] = "Modified"; 
                }
            }
            else    //旧表中无对应行
            {
                dr["Status"] = "Added";
            }
        }//至此,新表标志完毕,旧表只剩删除行未被标志    foreach (DataRow dr in dtOld.Rows)
        {
            if (dr["Status"].ToString().Length == 0)   //旧表中此行数据未被标志
            {
                dr["Status"] = "Delete";
            }
        }//至此,旧表删除行标志完毕
    }
    /*再次解释:drS 数组不开辟新内存,因为是主键检索,所以drS数组只能最多有一条数据
              并且修改drS[0]的某列的值,实质上就是修改了dtOld表中相应列的值 */