Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use LINQ Distinct() with multiple fields

Tags:

c#

linq

distinct

I have the following EF class derived from a database (simplified)

class Product {       public string ProductId;      public string ProductName;      public string CategoryId;      public string CategoryName; } 

ProductId is the Primary Key of the table.

For a bad design decision made by the DB designer (I cannot modify it), I have CategoryId and CategoryName in this table.

I need a DropDownList with (distinct) CategoryId as Value and CategoryName as Text. Therefore I applied the following code:

product.Select(m => new {m.CategoryId, m.CategoryName}).Distinct(); 

which logically it should create an anonymous object with CategoryId and CategoryName as properties. The Distinct() guarantees that there are no duplicates pair (CategoryId, CategoryName).

But actually it does not work. As far as I understood the Distinct() works just when there is just one field in the collection otherwise it just ignores them...is it correct? Is there any workaround? Thanks!

UPDATE

Sorry product is:

List<Product> product = new List<Product>(); 

I found an alternative way to get the same result as Distinct():

product.GroupBy(d => new {d.CategoryId, d.CategoryName})         .Select(m => new {m.Key.CategoryId, m.Key.CategoryName}) 
like image 580
CiccioMiami Avatar asked May 23 '12 12:05

CiccioMiami


People also ask

Why distinct is not working in Linq?

LINQ Distinct is not that smart when it comes to custom objects. All it does is look at your list and see that it has two different objects (it doesn't care that they have the same values for the member fields). One workaround is to implement the IEquatable interface as shown here.

How does Linq distinct work?

LINQ Distinct operator removes all the duplicate values from the collection and finally returns the dissimilar or unique values. The LINQ Distinct operator available in only Method Syntax and it not supports the Query Syntax. LINQ Distinct is an operator which comes under Set Operator.

Does Linq distinct use equals?

c# - Linq distinct doesn't call Equals method - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.


1 Answers

I assume that you use distinct like a method call on a list. You need to use the result of the query as datasource for your DropDownList, for example by materializing it via ToList.

var distinctCategories = product                         .Select(m => new {m.CategoryId, m.CategoryName})                         .Distinct()                         .ToList(); DropDownList1.DataSource     = distinctCategories; DropDownList1.DataTextField  = "CategoryName"; DropDownList1.DataValueField = "CategoryId"; 

Another way if you need the real objects instead of the anonymous type with only few properties is to use GroupBy with an anonymous type:

List<Product> distinctProductList = product     .GroupBy(m => new {m.CategoryId, m.CategoryName})     .Select(group => group.First())  // instead of First you can also apply your logic here what you want to take, for example an OrderBy     .ToList(); 

A third option is to use MoreLinq's DistinctBy.

like image 56
Tim Schmelter Avatar answered Oct 01 '22 01:10

Tim Schmelter