2

I'm attempting to implement IEqualityComparer so I can compare custom objects for equality and differences.

Scenario: I have 10 batches of record sets that were imported at different times. I need to look at the most recent record set, and compare it to the all previous record sets, and see which records have appeared before, and which records have appeared for the first time.

My code looks solid, and I can't figure out why this isn't working. It seems all the records are being distinguished as being previously present, and no records are ever new.

On a side note, my record loading is literally a million times faster if I just select into a var. Is there a way to setup IEqualityComparer on a var type? Or does it depend on a specific object type?

This is the code pulling the records:




    List currentRecords = (from importRecord in db.ImportRecords
                join i in db.Imports on importRecord.ImportId equals i.ImportId
                where i.ImportId == importId
                select new RecordLite
                {
                    RecordId = importRecord.RecordId,
                    IdCode = importRecord.IdCode,
                    IdText1 = importRecord.IdText1,
                    IdText2 = importRecord.IdText2,
                    UniqueId = importRecord.UniqueId,
                }).ToList();

            List historicalRecords = (from importRecord in db.ImportRecords
                join i in db.Imports on importRecord.ImportId equals i.ImportId
                where i.CustomerId == customerId
                select new RecordLite
                {
                    RecordId = importRecord.RecordId,
                    IdCode = importRecord.IdCode,
                    IdText1 = importRecord.IdText1,
                    IdText2 = importRecord.IdText2,
                    UniqueId = importRecord.UniqueId,
                }).ToList();

            List newRecords = currentRecords.Except(historicalRecords, new RecordLiteComparer()).ToList();
            List oldRecords = currentRecords.Intersect(historicalRecords, new RecordLiteComparer()).ToList();

This is my class & IEqualityComparer



    public class RecordLite
    {
        public int RecordId { get; set; }
        public string IdCode { get; set; }
        public string IdText1 { get; set; }
        public string IdText2 { get; set; }
        public string UniqueId { get; set; }
    }

    public class RecordLiteComparer : IEqualityComparer
    {
        public bool Equals(RecordLite x, RecordLite y)
        {
            if (object.ReferenceEquals(x, y))
                return true;

            if (x == null || y == null)
                return false;

            return x.IdCode.Equals(y.IdCode, StringComparison.CurrentCultureIgnoreCase);
        }

        public int GetHashCode(RecordLite obj)
        {
            return new { obj.IdCode }.GetHashCode();
        }
    }

mrb398
  • 1,277
  • 4
  • 24
  • 32

1 Answers1

1

Ok, I figured out the problem wasn't with code, it was with my logic.

When selecteing the previous records, I wasn't excluding the current record set. So when comparing, all records were considered old because all the records were present in the historical records, including the records I was trying to check against.

basically just needed to update to this line

where i.CustomerId == customerId && i.ImportId != importId
mrb398
  • 1,277
  • 4
  • 24
  • 32
  • That's called "code" too. Now to see if you can debunk your own "selecting into var is faster" statement ;) – Willem van Rumpt Oct 16 '14 at 13:41
  • Haha, I'd love to debunk or figure it out, but alas I have to keep pushing ahead for now to keep this critical project moving. The speed increase would be nice, but were only talking about saving 7 seconds to load up 3 million records. I'll probably look into this in the future though – mrb398 Oct 16 '14 at 13:49