【发布时间】:2014-03-21 21:14:34
【问题描述】:
在documentation查询表达式中,我发现:
请注意,连接表达式中 = 符号周围的键顺序很重要。
但是,我无法找到任何关于该顺序的重要性、它产生什么差异或使等式运算符不对称的基本原理的任何信息。
谁能解释或指出一些更好的文档?
【问题讨论】:
在documentation查询表达式中,我发现:
请注意,连接表达式中 = 符号周围的键顺序很重要。
但是,我无法找到任何关于该顺序的重要性、它产生什么差异或使等式运算符不对称的基本原理的任何信息。
谁能解释或指出一些更好的文档?
【问题讨论】:
这对于连接很重要。例如,如果您查看leftOuterJoin 的示例:
query {
for student in db.Student do
leftOuterJoin selection in db.CourseSelection on
(student.StudentID = selection.StudentID) into result
for selection in result.DefaultIfEmpty() do
select (student, selection)
}
顺序决定了出现“缺失”值时会发生什么。关键是文档中的这一行:
如果任何组为空,则使用具有单个默认值的组。
使用当前订单,db.Student 中的每个 StudentID 都将被表示,即使 db.CourseSelection 没有匹配的元素。如果您颠倒顺序,则相反 - 每个“课程选择”都将被表示,缺少students 将获得默认值。这意味着,在上述情况下,如果您切换顺序,任何没有选择课程的学生都不会在结果中显示,当前顺序始终显示每个学生。
【讨论】:
rightOuterJoin,因此顺序对于通过leftOuterJoin 或groupJoin 实现这一点至关重要。我认为文档明确提到了这一点作为解释的一种方式。
运算符左侧的表达式必须派生自要连接的“外部”事物,右侧的表达式必须派生自“内部”事物(正如您在对 Reed 答案的评论中提到的那样)。这是因为 LINQ API - 为构建查询而调用的实际方法类似于 this:
static member Join<'TOuter, 'TInner, 'TKey, 'TResult> :
outer:IQueryable<'TOuter> *
inner:IEnumerable<'TInner> *
outerKeySelector:Expression<Func<'TOuter, 'TKey>> *
innerKeySelector:Expression<Func<'TInner, 'TKey>> *
resultSelector:Expression<Func<'TOuter, 'TInner, 'TResult>> -> IQueryable<'TResult>
所以你不能加入任意的布尔表达式(你可以在 SQL 中做 - 像 JOIN ON a.x + b.y - 7 > a.w * b.z 这样的东西在 SQL 中很好,但在 LINQ 中不行),你只能基于显式投影之间的相等条件加入外表和内表。在我看来,这是一个非常不幸的设计决定,但它已从 LINQ 延续到 F#。
【讨论】: