Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IQueryable.Distinct()与List.Distinct()的比较_C#_Linq_Distinct_Iqueryable_Telerik Open Access - Fatal编程技术网

C# IQueryable.Distinct()与List.Distinct()的比较

C# IQueryable.Distinct()与List.Distinct()的比较,c#,linq,distinct,iqueryable,telerik-open-access,C#,Linq,Distinct,Iqueryable,Telerik Open Access,我有一个linq查询,我正在上使用Distinct()。如果我只调用Distinct(),而不转换为列表,那么它不会返回一个Distinct列表-它仍然包含重复项 但是,如果我转换为一个列表,然后调用Distinct(),它将按预期工作,并且我只得到唯一的对象 我使用的是Telerik ORM,返回的对象是表示数据库中一个表的类 var uniqueUsers = (from u in Database.Users select u).Distinct()

我有一个linq查询,我正在上使用
Distinct()
。如果我只调用
Distinct()
,而不转换为列表,那么它不会返回一个Distinct列表-它仍然包含重复项

但是,如果我转换为一个列表,然后调用
Distinct()
,它将按预期工作,并且我只得到唯一的对象

我使用的是Telerik ORM,返回的对象是表示数据库中一个表的类

var uniqueUsers = (from u in Database.Users 
                   select u).Distinct();
上面的代码不会产生不同的结果,但是,当我转换为列表并调用distinct时,它会:

var uniqueUsers = (from u in Database.Users 
                   select u).ToList().Distinct();
我怀疑这与转换为列表之前的集合有关,比较对对象的引用而不是对象数据本身,但我不完全理解发生了什么-为什么第一个代码示例没有产生唯一的结果,以及使用
.ToList()
时集合会发生什么情况,这使得它能够工作

[编辑]我简化了上述查询,在现实世界中,查询有几个连接,这些连接生成非唯一的结果,但我只返回用户对象

我尝试重写
Equals
GetHashCode
方法,但这没有任何区别

public override bool Equals(object obj)
{
    User comparingObject = obj as User ;

    if (comparingObject == null)
    {
        return false;
    }
    else
    {
        return comparingObject.UserID.Equals(this.UserID);
    }
}

public override int GetHashCode()
{
    return this.UserID.GetHashCode();
}
[更新]
在LinqPad中运行了相同的查询后,它可以按预期工作,提供一个不同条目的列表。然而,当使用Telerik ORM dll在LinqPad中运行相同的查询时,我会得到多个条目。因此,这似乎是Telerik的一个特点。当我有时间的时候,我会进一步调查,并在Telerik支持下提出它。

显然,您的表中不能有完全重复的行(包括主键)。可能您的意思是具有一些相等字段的行(不包括主键)

IQueryable
上调用
Distinct
,在生成的查询上生成一个SQL
Distinct
运算符,该运算符将表中的每个字段相互比较。由于表中不能有完全重复的行,因此它将返回所有行


另一方面,在
列表上调用
Distinct
将使用
User
对象的
Equals
方法来比较内存中的对象(从数据库中获取所有行之后)。最终的结果取决于
Equals
方法的实现,该方法只能检查一些字段的值是否相等。

您看过生成的SQL是什么样子吗?我不清楚,如果你只是列出一个表的内容,你怎么能在第一时间得到重复的内容。。。这似乎很奇怪。也许你在代码中覆盖了Jon Skeet所说的
Equals
。你覆盖了
User
对象的
Equals
方法了吗?如果是这样的话,你的两个案例之间会有很大的不同。@JonSkeet&MD.Unicorn-抱歉,我已经为这个问题添加了更多的细节。如果你能尝试提出一个最小的例子来说明问题,并包括为此生成的SQL,那将是很有帮助的。这可能是显而易见的,但也要注意在DB中这样做(iqeryable上的Distinct)的速度要快得多,因为每一行都不必传输到你的应用程序中,也不必转换为C#objects。我将此标记为答案-尽管这个问题似乎是一个Telerik ORM问题(因为它在LinqPad中工作正常)。这个答案向我阐明了
iqeryable.Distinct
ToList()的原理.Distinct
DISTINCE使我走上了确定问题的道路。当我有时间向Telerik提出问题并获得更多信息时,我将发布更新。这正是我要找的东西。+1 mate。