何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接

Posted

技术标签:

【中文标题】何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接【英文标题】:When to prefer joins expressed with SelectMany() over joins expressed with the join keyword in Linq 【发布时间】:2010-10-26 16:46:18 【问题描述】:

Linq 允许使用 join 关键字或使用 带有 where 关键字的 SelectMany()(即几个 from 关键字):

var personsToState = from person in persons
                     join state in statesOfUS
                     on person.State equals state.USPS
                     select new  person, State = state.Name ;
foreach (var item in personsToState)

    System.Diagnostics.Debug.WriteLine(item);


// The same query can be expressed with the query operator SelectMany(), which is
// expressed as two from clauses and a single where clause connecting the sequences.                     
var personsToState2 = from person in persons
                      from state in statesOfUS
                      where person.State == state.USPS
                      select new  person, State = state.Name ;
foreach (var item in personsToState2)

    System.Diagnostics.Debug.WriteLine(item);

我的问题:什么时候有目的地使用 join 样式,什么时候使用 where 样式, 一种风格的性能优于另一种风格吗?

【问题讨论】:

***.com/questions/197241/… 【参考方案1】:

对于本地查询,Join 由于其作为Athari mentioned 的键控查找而更有效,但是对于 LINQ to SQL (L2S),您将从SelectMany 获得更多里程。在 L2S 中,SelectMany 最终会根据您的查询在生成的 SQL 中使用某种类型的 SQL 连接。

请看一下 C# 4.0 In a Nutshell 的作者 Joseph/Ben Albahari 的 the LINQ Quiz 的问题 11 和 12。他们展示了不同类型的连接样本,并声明:

使用 LINQ to SQL,基于 SelectMany 连接是最灵活的,并且可以 执行 equi 和 non-equi 连接。 抛出 DefaultIfEmpty,你可以 也做左外连接!

此外,Matt Warren 有一篇关于此主题的详细博文,因为它与 IQueryable/SQL 相关,这里是:LINQ: Building an IQueryable provider - Part VII。

回到您使用哪个查询的问题上,您应该使用更具可读性的查询,并且可以让您轻松地表达自己并清楚地构建您的最终目标。除非您正在处理大型集合并已对这两种方法进行了分析,否则性能不应成为最初的关注点。在 L2S 中,您必须考虑 SelectMany 为您提供的灵活性,具体取决于您需要配对数据的方式。

【讨论】:

【参考方案2】:

Join 更高效,它使用 Lookup 类(Dictionary 的变体,单个键具有多个值)来查找匹配值。

【讨论】:

@Thomas Levesque 感谢您的指正,英语不是我的母语。

以上是关于何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接的主要内容,如果未能解决你的问题,请参考以下文章

何时更喜欢 JSON 而不是 XML?

何时更喜欢 XAMPP 而不是 Linux、Apache、MySQL 和 PHP 的完整安装

何时更喜欢 lambda 而不是带有 std::async 的打包任务? [复制]

LINQ操作符二:SelectMany

LinqToSQL Select 和 SelectMany vs Join [关闭]

Linq下有一个非常实用的SelectMany方法,很多人却不会用