Linq链式SELECT和DISTINCT运算符

3

我是LINQ的新手,有一个基本查询。

假设我有一个大的客户对象列表

List<Customer> c = null;
c = //Fetch from DB - resulting into 1000+ non-unique Customers;

如果我将列表转换为另一个类(缺乏更好的名称)-CustomerEntity的列表,然后按照以下方式挑选出不同的元素:

    var ce = c.Select(cust => new CustomerEntity() 
                     {
                         CustomerID = cust.CustID,
                         CustomerName = cust.CustName
                     }).Distinct(new CustomerEntityComparer()).ToList();

CustomerEntityComparer是一个类,它基于CustomerID比较两个CustomerEntity对象。 我的问题是: 如果Select和Distinct链接在一起,是否会导致对列表进行多次迭代?

谢谢, Vikas


什么是问题?你已经做了什么来调查它? - erikkallen
简单的回答是:不行。但你可以在数据库端执行这些转换(SELECT DISTINCT)... - Patryk Ćwiek
如果你想更深入地了解LINQ(针对对象)的内部工作原理,我推荐访问http://msmvps.com/blogs/jon_skeet/archive/2011/02/23/reimplementing-linq-to-objects-part-45-conclusion-and-list-of-posts.aspx。在这里,Jon Skeet重新实现了LINQ并解释了所有涉及的原则(例如列表何时被迭代)。然而,简单的答案是它只会迭代原始列表一次。 - Chris
谢谢 Chris。会查看那个链接的。 - Viking17
1个回答

2
为了给出更详细的回答:
你可能会注意到Select()返回IEnumerable,Distinct()也是一样。这是因为你基本上正在创建一个查询。在调用ToList()方法之前,不会进行任何选择或去重过滤。当执行ToList()方法时,整个查询都将被评估。这就是所谓的延迟执行。
这样做的优点是,你可以创建像这样的查询:
var ceQuery = c.Select(cust => new CustomerEntity() 
{
    CustomerID = cust.CustID,
    CustomerName = cust.CustName
}).Distinct(new CustomerEntityComparer());

每次"c"改变时,您只需重复使用相同的ceQuery即可获取最新的结果:
var ce = ceQuery.ToList();

很好,谢谢。我知道在LINQ To SQL的情况下,查询会被转换为表达式树,然后当请求执行时,该树将用于生成SQL。我也知道L2Objects的延迟执行方面。但是我不确定在L2Objects的情况下,即使使用延迟执行,这两个链接调用是否只会对集合进行一次迭代。我的疑问是,这取决于SELECT和DISTINCT操作的实现方式。因此想要再次确认。 - Viking17

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接