首页 > 解决方案 > How to Except<> specifing another key? Or faster way to differences two huge List<>?

问题描述

I have a list of AE_AlignedPartners items in the db, which I retrieve with:

List<AE_AlignedPartners> ae_alignedPartners_olds = ctx.AE_AlignedPartners.AsNoTracking().ToList();

Than, I got and serialize a new list (of the same object type) with JSON:

List<AE_AlignedPartners> ae_alignedPartners_news = GetJSONPartnersList();

Than I'm getting the intersections of both:

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();

Now, due of these intersections, I need to create two new lists, with the added items (ae_alignedPartners_news - intersections) and the deleted ones (ae_alignedPartners_olds - interesections). Here's the code:

// 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();

But with many records (~100k) it tooks too much time.

Is there a sort of Except<> specifing which key need to be compared? In my case its not p.ID (which is the Primary Key on the DB), but p.ObjectID.

Or any other faster way?

标签: c#.netperformancelinq

解决方案


There is an Except function that you can use with a custom comparer:

    class PartnerComparer : IEqualityComparer<AE_AlignedPartners>
    {
        // Partners are equal if their ObjectID's are equal.
        public bool Equals(AE_AlignedPartners x, AE_AlignedPartners y)
        {         
            //Check whether the partner's ObjectID's are equal.
            return x.ObjectID == y.ObjectID;
        }

        public int GetHashCode(AE_AlignedPartners ap) {
            return ap.ObjectId.GetHashCode();
        }
    }

   var intersect = ae_alignedPartners_news.Intersect(ae_alignedPartners_olds);
   var creates = ae_alignedPartners_news.Except(intersect, new PartnerComparer);
   var deletes = ae_alignedPartners_old.Except(intersect, new PartnerComparer);

This should give you a reasonable boost in performance.


推荐阅读