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");
}
借鉴一下对比算法