Reputation: 61
I have a List of products such as :
List<Product> products = new List<Product>();
products.Add( new Product{ ProductID=1,Category="Food",SubCategory="Snacks",Location="Tokyo"});
products.Add( new Product{ ProductID=1,Category="Food",SubCategory="Snacks",Location="Tokyo"});
products.Add( new Product{ ProductID=1,Category="Food",SubCategory="Snacks",Location="Tokyo"});
I need a simple query to find distinct records for products. I was doing something like:
products.Select(x=>x.ProductID||x=>x.Category||x=>x.SubCategory).Distinct().ToList();
Upvotes: 0
Views: 68
Reputation: 865
You need to update your product class by providing overrides for Equals and == != operators. Also provide the implementation for GetHashCode. Please note that a good GetHashCode implementation is necessary/suggested as equal items would return equal hashes.
SO has some good discussion on that here
Regardless product class should look something like this
public class Product
{
public int ProductID { get; internal set; }
public string Category { get; internal set; }
public string SubCategory { get; internal set; }
public string Location { get; internal set; }
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || !this.GetType().Equals(obj.GetType()))
{
return false;
}
else
{
Product p = (Product)obj;
return (ProductID == p.ProductID) &&
(Category == p.Category) &&
(Location == p.Location) &&
(SubCategory == p.SubCategory)
;
}
}
public static bool operator ==(Product b1, Product b2)
{
if (b1 is null)
return b2 is null;
return b1.Equals(b2);
}
public static bool operator !=(Product b1, Product b2)
{
return !(b1 == b2);
}
public override int GetHashCode()
{
//https://learn.microsoft.com/en-us/archive/blogs/ericlippert/guidelines-and-rules-for-gethashcode
return ProductID;
}
}
And then in your LINQ
products.Select(x => x).Distinct().ToList();
Hope this helps !
Upvotes: 2
Reputation: 7513
The Distinct
operator has an overload that takes an IEqualityComparer<T>
, so you could change Product
to implement that:
class Product : IEqualityComparer<Product>
{
public int ProductID { get; internal set; }
public string Category { get; internal set; }
public string SubCategory { get; internal set; }
public string Location { get; internal set; }
public bool Equals(Product x, Product y)
{
return
x.Category.Equals(y.Category) &&
x.Location.Equals(y.Location) &&
x.SubCategory.Equals(y.SubCategory);
}
public int GetHashCode(Product obj)
{
return ProductID;
}
}
Then your query could work like this:
var distinctProducts =
(from product in products
select product)
.Distinct(new Product())
.ToList();
Notice that I passed an instance of Product
, which implements IEqualityComparer<Product>
to Distinct
.
Upvotes: 3