如何优化此创建/更新/删除比较?

时间:2019-01-23 08:46:20

标签: c# .net performance linq entity-framework-6

我使用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时,它会变得非常非常慢。

您对改善整体有何建议?

1 个答案:

答案 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];
    //...
}