借鉴一下对比算法
1 /// <summary> /// 比较两个DataTable数据(结构相同,字段名不同) /// </summary> /// <param name="dtDest">来自数据库的DataTable</param> /// <param name="dtSrc">来自文件的DataTable</param> /// <param name="dtRetAdd">新增数据(dt2中的数据)</param> /// <param name="dtRetDel">删除的数据(dt2中的数据)</param> /// <param name="srcKeyFields">源关键字段名</param> /// <param name="destKeyFields">目标关键字段名,与源关键字段名对应</param> public static void CompareDt(DataTable dtSrc, DataTable dtDest, out DataTable dtRetAdd, out DataTable dtRetDel, string srcKeyFields, string destKeyFields) { //源记录集与目标记录集有一个为null则退出 if (dtSrc == null || dtDest == null) { dtRetDel = null; dtRetAdd = null; return; } //定义返回记录表 dtRetDel = dtSrc.Clone(); dtRetAdd = dtRetDel.Clone(); //参照列为空则退出 if (string.IsNullOrEmpty(srcKeyFields) || string.IsNullOrEmpty(destKeyFields)) return; //获得参照列列表 string[] srcFields = srcKeyFields.Split(',');//列名数组 string[] destFields = destKeyFields.Split(',');//列名数组 //参照列数目不一致则退出 if (srcFields.Length != destFields.Length) return; //按参照列排序源表和目标表 DataRow[] drSrc = dtSrc.Select("", srcKeyFields); DataRow[] drDest = dtDest.Select("", destKeyFields); //定义源表和目标表长度 int iSrcCount = drSrc.Length; int iDestCount = drDest.Length; //源表为空则目标表全部加入删除队列并返回 if (iSrcCount == 0) { foreach (DataRow row in drDest) { dtRetDel.Rows.Add(row.ItemArray); } return; } //目标表为空则源表全部加入新增队列并返回 if (iDestCount == 0) { foreach (DataRow row in drSrc) { dtRetAdd.Rows.Add(row.ItemArray); } return; } //定义源表和目标表指针 int iSrc = 0; int iDest = 0; //开始循环比对 while (iSrc < iSrcCount && iDest < iDestCount) { //定义列比对结果 int result = 0; object oSrc; object oDest; //循环比对列值 for (int colIndex = 0; colIndex < srcFields.Length; colIndex++) { //获得列值 oSrc = drSrc[iSrc][srcFields[colIndex]]; oDest = drDest[iDest][destFields[colIndex]]; //比较列值,不相等则退出循环 if (oSrc == DBNull.Value) { result = oDest == DBNull.Value ? 0 : -1; } else { result = oDest == DBNull.Value ? 1 : string.Compare(oSrc.ToString(), oDest.ToString(), false); } if (result != 0) break; } //检查行比较结果 switch (result) { ////源表小则将源表本行加入新增队列,同时移动源表指针 case -1: dtRetAdd.Rows.Add(drSrc[iSrc].ItemArray); iSrc++; break; ////相同两表同时移动指针 case 0: iSrc++; iDest++; break; ////目标表小则将目标表本行加入删除队列,同时移动目标表指针 case 1: dtRetDel.Rows.Add(drDest[iDest].ItemArray); iDest++; break; default: break; } } //源表到达最后一条,目标表未到达,则目标表剩余行全部加入删除队列 if (iDest < iDestCount) { for (int index = iDest; index < iDestCount; index++) { dtRetDel.Rows.Add(drDest[index].ItemArray); } } //目标表到达最后一条,源表未到达,则源表剩余行全部加入新增队列 else if (iSrc < iSrcCount) { for (int index = iSrc; index < iSrcCount; index++) { dtRetAdd.Rows.Add(drSrc[index].ItemArray); } } 121
对比算法,借鉴一下。
static void Main(string[] args) { DataTable dt1 = new DataTable(); dt1.Columns.Add("a", System.Type.GetType("System.String")); DataRow dr = dt1.NewRow(); dr["a"] = "1"; DataRow dr1 = dt1.NewRow(); dr1["a"] = "2"; dt1.Rows.Add(dr1); DataRow dr2 = dt1.NewRow(); dr2["a"] = "7"; dt1.Rows.Add(dr2); DataRow dr3 = dt1.NewRow(); dr3["a"] = "8"; dt1.Rows.Add(dr3); DataRow dr4 = dt1.NewRow(); dr4["a"] = "9"; dt1.Rows.Add(dr4); DataTable dt2=new DataTable (); dt2.Columns.Add("b", System.Type.GetType("System.String")); DataRow dr5 = dt2.NewRow(); dr5["b"] = "1"; dt2.Rows.InsertAt(dr5, 0); DataRow dr6 = dt2.NewRow(); dr6["b"] = "3"; dt2.Rows.InsertAt(dr6, 0); DataRow dr7 = dt2.NewRow(); dr7["b"] = "4"; dt2.Rows.InsertAt(dr7, 0); DataRow dr8 = dt2.NewRow(); dr8["b"] = "5"; dt2.Rows.InsertAt(dr8, 0); DataRow dr9 = dt2.NewRow(); dr9["b"] = "6"; dt2.Rows.InsertAt(dr9, 0); DataTable dt3=new DataTable (); DataTable dt4=new DataTable (); CompareDt(dt1,dt2,out dt3,out dt4,"a","b"); }