LINQ select distinct works as expected if you are returning a List of anonymous types or a List of a primitive type. But it seems not to work if you are returning a List of a class. The way to fix that is to implement IEqualitycomparer<T> interface and pass in an instance of that implementation to the the Distinct method. Its easier to understand this with a simple example.
The aim in the code below is to differentiate people based on their Social Security Number.
Code where select distinct does not work
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IEqualityComparer { class Program { static void Main(string[] args) { var people = new List<Person>(); people.Add(new Person { SocialSecurityNumber = "A", Name = "Pam" }); people.Add(new Person { SocialSecurityNumber = "B", Name = "John" }); people.Add(new Person { SocialSecurityNumber = "C", Name = "Susan" }); people.Add(new Person { SocialSecurityNumber = "D", Name = "Tom" }); people.Add(new Person { SocialSecurityNumber = "A", Name = "Pam" });//THIS RECORD IS REPEATED var distinctPeople = (from p in people select p).Distinct(); foreach (var person in distinctPeople) { Console.WriteLine(person.Name);//PAM GETS PRINTED TWICE, HENCE SELECT DISTINCT DOESNOT WORK } } } public class Person { public string SocialSecurityNumber { get; set; } public string Name { get; set; } } }
Output:
Pam
John
Susan
Tom
Pam
Press any key to continue . . .
Code where select distinct works
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IEqualityComparer { class Program { static void Main(string[] args) { var people = new List<Person>(); people.Add(new Person { SocialSecurityNumber = "A", Name = "Pam" }); people.Add(new Person { SocialSecurityNumber = "B", Name = "John" }); people.Add(new Person { SocialSecurityNumber = "C", Name = "Susan" }); people.Add(new Person { SocialSecurityNumber = "D", Name = "Tom" }); people.Add(new Person { SocialSecurityNumber = "A", Name = "Pam" }); var distinctPeople = (from p in people select p).Distinct(new PersonComparer());//Note that an implementation of IEqualityComparer<Person> is passed in foreach (var person in distinctPeople) { Console.WriteLine(person.Name); } } } public class Person { public string SocialSecurityNumber { get; set; } public string Name { get; set; } } public class PersonComparer : IEqualityComparer<Person> { public bool Equals(Person left, Person right) { if ((object)left == null && (object)right == null) { return true; } if ((object)left == null || (object)right == null) { return false; } return left.SocialSecurityNumber == right.SocialSecurityNumber; } public int GetHashCode(Person obj) { return obj.SocialSecurityNumber.GetHashCode(); } } }Output: Pam John Susan Tom Press any key to continue . . .
No comments:
Post a Comment
Comments will appear once they have been approved by the moderator