How to implement IEqualityComparer to return distinct values?

Bogdan Verbenets picture Bogdan Verbenets · Dec 19, 2011 · Viewed 67.8k times · Source

I have a L2E query that returns some data that contains duplicate objects. I need to remove those duplicate objects. Basically I should assume that if their IDs are the same then the objects are duplicate. I've tried q.Distinct(), but that still returned duplicate objects. Then I've tried implementing my own IEqualityComparer and passing it to the Distinct() method. The method failed with following text:

LINQ to Entities does not recognize the method 'System.Linq.IQueryable1[DAL.MyDOClass] Distinct[MyDOClass](System.Linq.IQueryable1[DAL.MyDOClass], System.Collections.Generic.IEqualityComparer`1[DAL.MyDOClass])' method, and this method cannot be translated into a store expression.

And here is the implementation of EqualityComparer:

  internal class MyDOClassComparer: EqualityComparer<MyDOClass>
    {
        public override bool Equals(MyDOClass x, MyDOClass y)
        {
            return x.Id == y.Id;
        }

        public override int GetHashCode(MyDOClass obj)
        {
            return obj == null ? 0 : obj.Id;
        }
    }

So how do I write my own IEqualityComparer properly?

Answer

Rich O&#39;Kelly picture Rich O'Kelly · Dec 19, 2011

An EqualityComparer is not the way to go - it can only filter your result set in memory eg:

var objects = yourResults.ToEnumerable().Distinct(yourEqualityComparer);

You can use the GroupBy method to group by IDs and the First method to let your database only retrieve a unique entry per ID eg:

var objects = yourResults.GroupBy(o => o.Id).Select(g => g.First());