IQueryable.Distinct()vs List.Distinct()

Chr*_*s B 4 c# linq iqueryable distinct telerik-open-access

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

但是,如果我转换为List 然后调用Distinct()- 它按预期工作,我只获得唯一的对象.

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

var uniqueUsers = (from u in Database.Users 
                   select u).Distinct();
Run Code Online (Sandbox Code Playgroud)

上面的代码不会产生不同的结果,但是当我转换为列表并调用distinct时 - 它确实:

var uniqueUsers = (from u in Database.Users 
                   select u).ToList().Distinct();
Run Code Online (Sandbox Code Playgroud)

我怀疑这与转换到列表之前的集合有关,比较对象的引用而不是对象数据本身但我不完全理解发生了什么 - 为什么第一个代码示例不会产生独特的结果以及会发生什么使用时的集合.ToList()使它工作?

[编辑]我已经简化了上面的查询,在现实世界中,查询有几个连接,它们会生成非唯一的结果,但是我只返回User对象.

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

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();
}
Run Code Online (Sandbox Code Playgroud)

[更新] 在LinqPad中运行相同的查询后,它按预期工作,提供不同条目的列表.但是在使用Telerik ORM dll时在LinqPad中运行相同的查询我会得到多个条目.所以它似乎是Telerik的特色.当我有空的时候,我会进一步调查并通过Telerik的支持来提高它.

Moh*_*han 9

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

调用,DistinctIQueryable生成的DISTINCT查询上生成一个SQL 运算符,该运算符将表的每个字段相互比较.因为表中没有完全重复的行,所以它返回所有行.

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