C# 比较Linq
我在数据库中有一堆数据,我想为它们编写一个搜索函数。问题是我得到了很多复制品。 数据是以姓名和姓氏为结构的,我只想发送两种数据中唯一的一种,因此如果我有两个人的名字是Foo,姓氏栏中只会显示一个 不管我怎么想,我总是回到我需要比较它们的地方C# 比较Linq,c#,linq,C#,Linq,我在数据库中有一堆数据,我想为它们编写一个搜索函数。问题是我得到了很多复制品。 数据是以姓名和姓氏为结构的,我只想发送两种数据中唯一的一种,因此如果我有两个人的名字是Foo,姓氏栏中只会显示一个 不管我怎么想,我总是回到我需要比较它们的地方 var names = db.People .Where(r => r.Name.Contains(q)) .OrderBy(r=> r.Name) *Psuedo-Code* if((this
var names = db.People
.Where(r => r.Name.Contains(q))
.OrderBy(r=> r.Name)
*Psuedo-Code*
if((this.Name==next.Name)&&(this.surSame==next.Surname)
toss next data and loop to next
*Psuedo-Code*
.Take(5);
也许有点混乱,但你知道我想要实现什么。我可以用某种方式来实现这一点,还是有更好的方法来实现这一点?使用Distinct()
并在人员类中实现方法Equals
,或者使用辅助类来比较它们:
public class PeopleComparer : IEqualityComparer<People>
{
public bool Equals(People x, People y)
{
return x.Name == y.Name && x.Surname == y.Surname;
}
public int GetHashCode(People obj)
{
unchecked
{
return (obj.Name.GetHashCode() * 31) + obj.Surname.GetHashCode();
}
}
}
公共类PeopleComparer:IEqualityComparer
{
公共布尔等于(人x,人y)
{
返回x.Name==y.Name&&x.姓氏==y.姓氏;
}
公共int GetHashCode(人员对象)
{
未经检查
{
return(obj.Name.GetHashCode()*31)+obj.姓氏.GetHashCode();
}
}
}
您可以这样做:
var names = db.People
.Where(r => r.Name.Contains(q))
.Select(r => new { Name = r.Name, Surname = r.Surname })
.Distinct()
.Take(5);
但如果因为你需要全民记录而无法实现,你只需要第一个,我已经成功地完成了这样的工作:
var names = db.People
.Where(r => r.Name.Contains(q))
.GroupBy(r => new { Name = r.Name, Surname = r.Surname })
.Select(g => g.First())
.Take(5);
Distinct
在People
类中使用Equals
是正确的方法,但这里有一个更“内联”的替代方法:
听起来像是。Distinct
可能适用于您的目的。是的,我已经尝试过了,但没有想到如何使用它。如果我的名字或姓氏不同,我只会得到一个。什么是db
?或者:这是linq to sql吗?您还需要一个合理的GetHashCode
实现。是的,我认为最好像现在这样将GetHashCode
计算委托给People
类。不,实际上,一点也不。事实上,这样做破坏了实现。哈希代码和等式必须基于同一个“东西”。散列代码应该基于姓名和姓氏,就像等式一样。好吧,我想你是想把代码移到People
类,因为如果他实现Equals
,那么GetHashCode
计算应该是相同的。因此,第一个版本已经足够好了,因为它使用一个素数乘以第一个哈希代码。您还需要将GetHashCode
的主体包装为unchecked{…}
。看起来您的答案和我一样,快了1分钟。new{Name=r.Name,lasname=r.lasname}
匿名类型声明实际上可以替换为更短但等效的new{r.Name,r.lasname}
,如果您愿意的话。谢谢!我正要把我的笔记本电脑扔出窗外。我唯一需要做的改变是使用“FirstorDefault”,而不是使用其他函数的first。再次,非常感谢。这让我很开心!:)
var names = db.People
.Where(r => r.Name.Contains(q))
.GroupBy(r => new { r.Name, r.Surname })
.Select(g => g.First())
.OrderBy(r => r.Name)
.Take(5);