代码
///
<summary>
/// 比较两个DataTable数据(结构相同)
/// </summary>
/// <param name="dt1"> 来自数据库的DataTable </param>
/// <param name="dt2"> 来自文件的DataTable </param>
/// <param name="keyField"> 关键字段名 </param>
/// <param name="dtRetAdd"> 新增数据(dt2中的数据) </param>
/// <param name="dtRetDif1"> 不同的数据(数据库中的数据) </param>
/// <param name="dtRetDif2"> 不同的数据(图2中的数据) </param>
/// <param name="dtRetDel"> 删除的数据(dt2中的数据) </param>
public static void CompareDt(DataTable dt1, DataTable dt2, string keyField,
out DataTable dtRetAdd, out DataTable dtRetDif1, out DataTable dtRetDif2,
out DataTable dtRetDel)
{
// 为三个表拷贝表结构
dtRetDel = dt1.Clone();
dtRetAdd = dtRetDel.Clone();
dtRetDif1 = dtRetDel.Clone();
dtRetDif2 = dtRetDel.Clone();
int colCount = dt1.Columns.Count;
DataView dv1 = dt1.DefaultView;
DataView dv2 = dt2.DefaultView;
// 先以第一个表为参照,看第二个表是修改了还是删除了
foreach (DataRowView dr1 in dv1)
{
dv2.RowFilter = keyField + " = ' " + dr1[keyField].ToString() + " ' " ;
if (dv2.Count > 0 )
{
if ( ! CompareUpdate(dr1, dv2[ 0 ])) // 比较是否有不同的
{
dtRetDif1.Rows.Add(dr1.Row.ItemArray); // 修改前
dtRetDif2.Rows.Add(dv2[ 0 ].Row.ItemArray); // 修改后
dtRetDif2.Rows[dtRetDif2.Rows.Count - 1 ][ " FID " ] = dr1.Row[ " FID " ]; // 将ID赋给来自文件的表,因为它的ID全部==0
continue ;
}
}
else
{
// 已经被删除的
dtRetDel.Rows.Add(dr1.Row.ItemArray);
}
}
// 以第一个表为参照,看记录是否是新增的
dv2.RowFilter = "" ; // 清空条件
foreach (DataRowView dr2 in dv2)
{
dv1.RowFilter = keyField + " = ' " + dr2[keyField].ToString() + " ' " ;
if (dv1.Count == 0 )
{
// 新增的
dtRetAdd.Rows.Add(dr2.Row.ItemArray);
}
}
}
// 比较是否有不同的
private static bool CompareUpdate(DataRowView dr1, DataRowView dr2)
{
// 行里只要有一项不一样,整个行就不一样,无需比较其它
object val1;
object val2;
for ( int i = 1 ; i < dr1.Row.ItemArray.Length; i ++ )
{
val1 = dr1[i];
val2 = dr2[i];
if ( ! val1.Equals(val2))
{
return false ;
}
}
return true ;
}
/// 比较两个DataTable数据(结构相同)
/// </summary>
/// <param name="dt1"> 来自数据库的DataTable </param>
/// <param name="dt2"> 来自文件的DataTable </param>
/// <param name="keyField"> 关键字段名 </param>
/// <param name="dtRetAdd"> 新增数据(dt2中的数据) </param>
/// <param name="dtRetDif1"> 不同的数据(数据库中的数据) </param>
/// <param name="dtRetDif2"> 不同的数据(图2中的数据) </param>
/// <param name="dtRetDel"> 删除的数据(dt2中的数据) </param>
public static void CompareDt(DataTable dt1, DataTable dt2, string keyField,
out DataTable dtRetAdd, out DataTable dtRetDif1, out DataTable dtRetDif2,
out DataTable dtRetDel)
{
// 为三个表拷贝表结构
dtRetDel = dt1.Clone();
dtRetAdd = dtRetDel.Clone();
dtRetDif1 = dtRetDel.Clone();
dtRetDif2 = dtRetDel.Clone();
int colCount = dt1.Columns.Count;
DataView dv1 = dt1.DefaultView;
DataView dv2 = dt2.DefaultView;
// 先以第一个表为参照,看第二个表是修改了还是删除了
foreach (DataRowView dr1 in dv1)
{
dv2.RowFilter = keyField + " = ' " + dr1[keyField].ToString() + " ' " ;
if (dv2.Count > 0 )
{
if ( ! CompareUpdate(dr1, dv2[ 0 ])) // 比较是否有不同的
{
dtRetDif1.Rows.Add(dr1.Row.ItemArray); // 修改前
dtRetDif2.Rows.Add(dv2[ 0 ].Row.ItemArray); // 修改后
dtRetDif2.Rows[dtRetDif2.Rows.Count - 1 ][ " FID " ] = dr1.Row[ " FID " ]; // 将ID赋给来自文件的表,因为它的ID全部==0
continue ;
}
}
else
{
// 已经被删除的
dtRetDel.Rows.Add(dr1.Row.ItemArray);
}
}
// 以第一个表为参照,看记录是否是新增的
dv2.RowFilter = "" ; // 清空条件
foreach (DataRowView dr2 in dv2)
{
dv1.RowFilter = keyField + " = ' " + dr2[keyField].ToString() + " ' " ;
if (dv1.Count == 0 )
{
// 新增的
dtRetAdd.Rows.Add(dr2.Row.ItemArray);
}
}
}
// 比较是否有不同的
private static bool CompareUpdate(DataRowView dr1, DataRowView dr2)
{
// 行里只要有一项不一样,整个行就不一样,无需比较其它
object val1;
object val2;
for ( int i = 1 ; i < dr1.Row.ItemArray.Length; i ++ )
{
val1 = dr1[i];
val2 = dr2[i];
if ( ! val1.Equals(val2))
{
return false ;
}
}
return true ;
}