我使用EF 6。
我在数据库中有一个当前项目的列表,可以使用以下列表进行检索:
ae_alignedPartners_olds = ctx.AE_AlignedPartners.AsNoTracking().ToList(); // list of List<AE_AlignedPartners>
然后,我使用JSON重试相同的对象,
ae_alignedPartners_news = GetJSONListObjects(); // list of List<AE_AlignedPartners>
与我进行一些比较(以查看需要更新的内容,需要删除的内容和要创建的内容。这是当前代码:
// intersection
var IDSIntersections = (from itemNew in ae_alignedPartners_news
join itemOld in ae_alignedPartners_olds on itemNew.ObjectID equals itemOld.ObjectID
select itemNew).Select(p => p.ObjectID).ToList();
// to update
IList<AE_AlignedPartners> ae_alignedPartners_toUpdate = new List<AE_AlignedPartners>();
foreach (var item in IDSIntersections)
{
var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);
var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);
if (itemOld.Field1 != itemNew.Field1 ||
itemOld.Field2 != itemNew.Field2 ||
itemOld.Field3 != itemNew.Field3 ||
itemOld.Field4 != itemNew.Field4 ||
itemOld.Field5 != itemNew.Field5 ||
itemOld.Field6 != itemNew.Field6 ||
itemOld.Field7 != itemNew.Field7 ||
itemOld.Field8 != itemNew.Field8 ||
itemOld.Field9 != itemNew.Field9)
{
itemOld.Field1 = itemNew.Field1;
itemOld.Field2 = itemNew.Field2;
itemOld.Field3 = itemNew.Field3;
itemOld.Field4 = itemNew.Field4;
itemOld.Field5 = itemNew.Field5;
itemOld.Field6 = itemNew.Field6;
itemOld.Field7 = itemNew.Field7;
itemOld.Field8 = itemNew.Field8;
itemOld.Field9 = itemNew.Field9;
ae_alignedPartners_toUpdate.Add(itemOld);
}
}
// to create
IList<AE_AlignedPartners> ae_alignedPartners_toCreate = ae_alignedPartners_news.Where(p => !IDSIntersections.Contains(p.ObjectID)).ToList();
// to delete
IList<AE_AlignedPartners> ae_alignedPartners_toDelete = ae_alignedPartners_olds.Where(p => !IDSIntersections.Contains(p.ObjectID)).ToList();
哪一个更快,足以存储1000个记录?超过50k时,它会变得非常非常慢。
您对改善整体有何建议?
答案 0 :(得分:1)
如果您想找出运行缓慢的地方,建议您进行概要分析或仅将调试器暂停10次以查看其最经常停止的位置(您可以使用现有代码尝试此操作)。但是在这里我可以立即发现问题:
var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);
var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);
这正在扫描整个列表,即O(N)。连同外循环一起变成O(N ^ 2)。
最好的解决方案是重组查询,这样就不必进行这些查询了。在我看来,联接已经输出了您需要的对象。
但是您也可以使用哈希表来加快查找速度。
var dict_ae_alignedPartners_olds = ae_alignedPartners_olds.ToDictionary(p => p.ObjectID);
var dict_ae_alignedPartners_news = ae_alignedPartners_news.ToDictionary(p => p.ObjectID);
foreach (var item in IDSIntersections)
{
var itemOld = dict_ae_alignedPartners_olds[item];
var itemNew = dict_ae_alignedPartners_news[item];
//...
}