IQueryable.Distinct()与List.Distinct() [英] IQueryable.Distinct() vs List.Distinct()

查看:664
本文介绍了IQueryable.Distinct()与List.Distinct()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a linq query that I am using Distinct() on. If I just call Distinct() without converting to a List then it does not return a distinct list - it still contains duplicates.

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

However if I convert to a List and then call Distinct() - it works as expected and I only get unique objects.

我正在使用Telerik ORM,返回的对象是代表数据库中表之一的类.

I'm using Telerik ORM and the objects being returned are the class representing one of the tables in the database.

var uniqueUsers = (from u in Database.Users 
                   select u).Distinct();

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

The code above does not produce distinct results, however when I convert to a list and call distinct - it does:

var uniqueUsers = (from u in Database.Users 
                   select u).ToList().Distinct();

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

I suspect this has to do with the collection before being converted to a list, comparing references to objects rather than the object data itself but I do not fully understand what is going on - why does the fist code example not produce unique results and what happens to the collection when using .ToList() that makes it work?

我简化了上面的查询,在现实世界中,该查询具有多个联接,这些联接生成非唯一结果,但是我只返回User对象.

I've simplified the above queries, in the real world the query has several joins which generates non-unique results, however I am returning just the User objects.

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

I tried overriding the Equals and GetHashCode methods but this did not make any difference.

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();
}

[UPDATE] 在LinqPad中运行了相同的查询后,它可以按预期方式工作,并提供了一系列不同的条目.但是,当使用Telerik ORM dll在LinqPad中运行相同的查询时,我会得到多个条目.因此,似乎是与Telerik的特殊之处.有空的时候,我将进一步调查并在Telerik的支持下进行调查.

[UPDATE] Having run the same query in LinqPad, it works as expected providing a list of distinct entries. However running the same query in LinqPad when using the Telerik ORM dll I get multiple entries. So it appears to be a peculiarity with Telerik. When I have time I will investigate further and raise it with Telerik support.

推荐答案

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

Obviously you cannot have exact duplicate rows (including the primary key) in your table. Probably what you mean is rows with some equal fields (excluding primary key).

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

Calling Distinct on IQueryable, generates a SQL DISTINCT operator on the resulting query, which compares every field of your table against each other. Because you cannot have exact duplicate rows in the table, it returns all the rows.

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

On the other hand, calling Distinct on a List<User> will use Equals method of the User object to compare objects in memory (after fetching all the rows from database). The final result depends on the implementation of Equals method, which could check only some fields for equal values.

这篇关于IQueryable.Distinct()与List.Distinct()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆