Tuesday, April 3, 2012

LINQ - Distinct() not working as expected

Issue: 

When using custom classes not generated by LINQ to SQL, Distinct() is unable to determine that two objects might be the same based on a key or all values within the objects, and simply sees two different objects regardless.

Solution:

Distinct() has an overload which takes an IEqualityComparer, thus allowing you to specify the value or values in which to compare and determine uniqueness upon.

Ex: For simplicity, lets say the list of clients passed in has duplicates. OID is organization id, and CID is client id.


            public static IEnumerable<CustomClient> GetClientsByOrganizationID(IEnumerable<CustomClient> clients, int oid)
            {
                using (DataContext db = new DataContext())
                {
                    db.DeferredLoadingEnabled = false;

                    var query = from c in clients
                                join o in db.Organizations on c.OID equals o.OID
                                where o.OID == oid
                                select c;

                    return query.Distinct(new ClientComparer()).ToList();
                }
            }


            public class ClientComparer : IEqualityComparer<CustomClient>
            {
                public bool Equals(CustomClient x, CustomClient y)
                {
                    return x.CID == y.CID;
                }

                public int GetHashCode(CustomClient obj)
                {
                    return obj.CID.GetHashCode();
                }
            }

1 comment:

  1. Could you not make CustomClient implement IEquatable or IComparable to make Distinct() work as expected?

    ReplyDelete