[英]How to get distinct items from a LINQ query in C#?
我有一个查询,它的定义是这样的,我用它来生成JSON输出。 关键是,我已经对其应用了Distinct方法,但是它仍然显示重复项。 例如,我有许多项的值为“未分类”,而我只想要其中一项,其他一些值也是如此。 这是我的查询:
var results = db.Users.OfType<Business>()
.Where(b => b.StateID == state && (term == null || b.Description.ToLower().Contains(term.ToLower())))
.Distinct().Select(x => new { id = x.StateID, value = x.Description }).Take(5).ToList();
任何想法,如何解决? 我想我需要以某种方式专门将Distinct应用于该值。
我怀疑您需要切换“非Distinct
和“ Select
呼叫。 Distinct
将比较比给定投影可能期望的更多字段,这可能意味着正在比实际要比较的字段进行比较。 首先调用“ Select
将减少进行比较以生成唯一列表的字段数。
即
var results = db.Users.OfType<Business>()
.Where(b => b.StateID == state && (term == null || b.Description.ToLower().Contains(term.ToLower())))
.Select(x => new { id = x.StateID, value = x.Description })
.Distinct()
.Take(5)
.ToList();
.NET无法知道您如何确定对象中的“平等”。 默认情况下,引用类型的相等性仅基于引用相等性,因此默认情况下,所有对象都是不同的。
您可以为Distinct()
提供一个自定义的相等比较器 。 例如,如果您只是在比较.Name
属性以确定唯一性,它可能看起来像这样:
class BusinessComparer : IEqualityComparer<Business>
{
public bool Equals(Business x, Business y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.Name == y.Name;
}
public int GetHashCode(Business business)
{
if (Object.ReferenceEquals(business, null))
return 0;
int hashBusinessName = business.Name == null ? 0 : business.Name.GetHashCode();
return hashProductName;
}
}
如果这种平等是核心业务逻辑,而不仅仅是在特定的比较中使用,则您甚至可以在Business
本身上实现Equals
和GetHashCode
,以便可以在其他地方使用平等比较。 请注意,这可能是对已经假定引用相等的现有代码的重大更改。
Business
类需要重写object.Equals
和object.GetHashCode
方法和实现IEquatable<T>
前的Distinct
方法将正常工作。
请参见MSDN示例: Enumerable.Distinct方法(IEnumerable)
通过使用默认的相等比较器比较值, Distinct()
返回序列中的不同元素。 因此,您应该创建BusinessEqualityComparer类,并应实现IEqualityComparer接口
class BusinessEqualityComparer : IEqualityComparer<Business>
{
public bool Equals(Business b1, Business b2)
{
if (b1.ID == b2.ID)
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(Business business)
{
int hCode = business.ID ^ business.ID ^ business.ID;
return hCode.GetHashCode();
}
不提供手动比较器的.Distinct()
将使用已处理类型的默认比较器,该类型将最终使用您的Business
类的.Equals()
和.GetHashCode()
。
因此,除非您重写了这些方法, .Distinct()
将仅删除引用方式的重复项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.