-1

I have two Generic List object, I want to get records which are not matching in second Generic list object. Below is my code. But it returning all records.

I want to ignore matching record in first list.

public class CuratedIncludeUid
    {
        public string type { get; set; }
        public string uid { get; set; }
    }

List<CuratedIncludeUid> newUids = new List<CuratedIncludeUid>();
            newUids.Add(new CuratedIncludeUid { type = "series", uid = "600" });

            List<CuratedIncludeUid> liExistingUids = new List<CuratedIncludeUid>();
            liExistingUids.Add(new CuratedIncludeUid { type = "series", uid = "600" });
            liExistingUids.Add(new CuratedIncludeUid { type = "series", uid = "200" });

            var ied = liExistingUids.Except(newUids).ToList(); ;
            foreach (var row in ied)
            {
                Console.WriteLine("Uid:" + row.uid + "type:" + row.type);
            }
            Console.Read();

I am getting Output as below 
Uid:600type:series
Uid:200type:series

**My expected output as below
Uid:200type:series**
Shakeer Hussain
  • 2,230
  • 7
  • 29
  • 52

2 Answers2

1

Either override Equals and GetHashCode

public class CuratedIncludeUid
{
    public string type { get; set; }
    public string uid { get; set; }

    protected bool Equals(CuratedIncludeUid other)
    {
        return string.Equals(type, other.type) && string.Equals(uid, other.uid);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        return Equals((CuratedIncludeUid) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((type != null ? type.GetHashCode() : 0) * 397) ^ (uid != null ? uid.GetHashCode() : 0);
        }
    }
}

Or passing an IEqualityComparer to Except

public class CuratedIncludeUidEqualityComparer : IEqualityComparer<CuratedIncludeUid>
{
    public bool Equals(CuratedIncludeUid x, CuratedIncludeUid y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
        return string.Equals(x.type, y.type) && string.Equals(x.uid, y.uid);
    }

    public int GetHashCode(CuratedIncludeUid obj)
    {
        unchecked
        {
            return ((obj.type != null ? obj.type.GetHashCode() : 0) * 397) ^ (obj.uid != null ? obj.uid.GetHashCode() : 0);
        }
    }
}
var ied = liExistingUids.Except(newUids, new CuratedIncludeUidEqualityComparer()).ToList();
nosale
  • 808
  • 6
  • 14
  • 1
    When overriding `Equals` and `GetHashCode` it is crucial that the object be read-only or, at least, the hash code doesn't change with the properties/fields do. – Enigmativity Jan 10 '19 at 23:38
-1

Either, you can implement Equals and GetHashCode or IEqualityComparer, or you can also do the following:

With All:

var ied = liExistingUids.Except(newUids).ToList();
liExistingUids
  .Where(x => newUids.All(y => y.type != x.type && y.series != x.series))
  .ToList();

With Any:

liExistingUids
  .Where(x => !newUids.Any(y => y.type == x.type && y.series == x.series))
  .ToList();
Gauravsa
  • 6,330
  • 2
  • 21
  • 30