最近项目上有一个功能,要求是实时采集和更新可售商品记录。可售商品信息来源于另外一套销售系统的接口。
通常可售商品记录在8万条左右,采集的数据不提供主键,按照一系列的字段内容识别是否相同,好多字段为null值。(所以无法进行主键比较)
采集和保存的业务规则是:
从采集的数据中对照数据库中,采集的数据中存在而库中不存在的商品,属于新增加的商品记录,需要增加到库中。
而库中存在但采集的数据中不存在的,则属于已经销售的商品,需要从库中删除。
为此查阅了很多xdjm的代码,给出了若干解决方法。
可惜在数据量很小的情况还行,当使用实际数据进行时,对照时间已经不能忍受。
代码如下:
- /// <summary>
- /// 比较两个DataTable数据(结构相同)mail:yx_007@163.com
- /// </summary>
- /// <param name="dtDest">来自数据库的DataTable</param>
- /// <param name="dtSrc">来自文件的DataTable</param>
- /// <param name="dtRetAdd">新增数据(dt2中的数据)</param>
- /// <param name="dtRetDel">删除的数据(dt2中的数据)</param>
- /// <param name="keyFields">关键字段名</param>
- public static void CompareDt(DataTable dtSrc, DataTable dtDest, out DataTable dtRetAdd, out DataTable dtRetDel, string keyFields)
- {
- dtRetDel = dtSrc.Clone();
- dtRetAdd = dtRetDel.Clone();
- StringBuilder sSrc = new StringBuilder();
- StringBuilder sDest = new StringBuilder();
- string[] sFields = keyFields.Split(',');//列名数组
- int iSrcCount = dtSrc.Rows.Count;
- int iDestCount = dtDest.Rows.Count;
- int iSrc = 0;
- int iDest = 0;
- int result = 0;
- bool isRun = true;
- dtSrc.Select("", keyFields);
- dtDest.Select("", keyFields);
- while (isRun)
- {
- if (iSrcCount == 0)//
- {
- dtRetDel = dtDest;
- isRun = false;
- continue;
- }
- if (iDestCount == 0)
- {
- dtRetAdd = dtDest;
- isRun = false;
- continue;
- }
- sSrc.Length = 0;
- sDest.Length = 0;
- for (result = 0; result < sFields.Length; result )
- {
- sSrc.Append(dtSrc.Rows[iSrc][sFields[result]]).Append(",");
- sDest.Append(dtDest.Rows[iDest][sFields[result]]).Append(",");
- }
- result = string.Compare(sSrc.ToString(), sDest.ToString(), true);
- switch (result)
- {
- ////src表小则新增src表
- case -1:
- dtRetAdd.Rows.Add(dtSrc.Rows[iSrc].ItemArray);
- iSrc ;
- break;
- ////相同同时向下移动
- case 0:
- iSrc ;
- iDest ;
- break;
- ////src表大则删除dest表
- case 1:
- dtRetDel.Rows.Add(dtDest.Rows[iDest].ItemArray);
- iDest ;
- break;
- }
- //检查是否已经移动到最后一条
- if ((iSrc == iSrcCount - 1) && (iDest < iDestCount - 1))
- {
- for (result = iDest; result < iDestCount; result )
- {
- dtRetDel.Rows.Add(dtDest.Rows[result].ItemArray);
- }
- isRun = false;
- continue;
- }
- if ((iSrc < iSrcCount - 1) && (iDest == iDestCount - 1))
- {
- for (result = iSrc; result < iSrcCount; result )
- {
- dtRetAdd.Rows.Add(dtSrc.Rows[result].ItemArray);
- }
- isRun = false;
- continue;
- }
- if ((iSrc == iSrcCount - 1) && (iDest == iDestCount - 1))
- {
- isRun = false;
- continue;
- }
- }
- }