Q:

Distinct() on Class, anonymus type and SelectListItem

I want to select all categories from a webservice. The webservice does not have a method for that, so I have to get all products, then select all categories that these products are in. When I recieve the data from the webservice, I make WebServiceProduct (ID, Name, etc) and WebServiceCategory (ID, Name, etc) objects of it.
This does not work:
        IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts()
                                                 from c in p.Categories
                                                 select new SelectListItem
                                                 {
                                                     Value = c.ID.ToString(),
                                                     Text = c.Name
                                                 }).Distinct().OrderBy(c => c.Text);

But it works when I first select it as a anonymus type:
        var foo = (from p in webserviceProductRepository.GetProducts()
                   from c in p.Categories
                   select new
                   {
                       ID = c.ID.ToString(),
                       Name = c.Name
                   }).Distinct().OrderBy(c => c.Name);

        IQueryable<SelectListItem> categories = from c in foo
                                                select new SelectListItem
                                                {
                                                    Value = c.ID.ToString(),
                                                    Text = c.Name
                                                };

I have also tried with a IEqualityComparer and overrided Equals and GetHashCode to check on WebServiceCategory.ID, but it does not work either.
So my question are, why is Distinct() working better on a anonymus type than on my WebServiceCategory object and SelectListItem?

A:

Anonymous types have value equality. Reference types have reference equality. LINQ to Entities is following the default semantics for the types. But overriding Equals or implementing IEquatable won't work, because LINQ to Entities queries are translated to SQL, and LINQ to Entities cannot translate arbitrary C# code to SQL. Note that the overloads of, e.g., Distinct which take a comparer aren't supported in L2E.
You have one workaround already, in your second code example. Another would be to group by an anonymous type:
var categories = from p in webserviceProductRepository.GetProducts()
                 from c in p.Categories
                 group c by new { Id = c.ID, Name = c.Name } into g
                 order by g.Key.Name
                 select new SelectListItem
                 {
                     Value = g.Key.Id.ToString(),
                     Text = g.Key.Name
                 };

