【问题标题】:How do query expression joins depend on the order of keys?查询表达式连接如何依赖于键的顺序?
【发布时间】:2014-03-21 21:14:34
【问题描述】:

documentation查询表达式中,我发现:

请注意,连接表达式中 = 符号周围的键顺序很重要。

但是,我无法找到任何关于该顺序的重要性、它产生什么差异或使等式运算符不对称的基本原理的任何信息。

谁能解释或指出一些更好的文档?

【问题讨论】:

    标签: f# f#-3.0 f#-4.0


    【解决方案1】:

    这对于连接很重要。例如,如果您查看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 将获得默认值。这意味着,在上述情况下,如果您切换顺序,任何没有选择课程的学生都不会在结果中显示,当前顺序始终显示每个学生。

    【讨论】:

    • 是不是已经通过“左外连接”而不是“右外连接”确定了不匹配的处理方式?如果我在做一个内部连接,那它有什么关系呢?
    • @JohannHibschman 使用简单的连接,没关系(文档在此处具有误导性)。在其他加入选项中,这很重要。请注意,查询表达式没有rightOuterJoin,因此顺序对于通过leftOuterJoingroupJoin 实现这一点至关重要。我认为文档明确提到了这一点作为解释的一种方式。
    • 在某些句法层面上似乎很重要。如果我执行“for a in X join b in Y on (b.id = a.id)”,VS 似乎无法将“b.id”中的“b”解析为任何内容,而如果我加入“on” (a.id = b.id)”,一切似乎都正常。不过,我不太喜欢通过智能感知进行实验性编程,所以我想了解发生了什么。
    • 关于 Johann Hibschman 的问题:有没有人找到解决方案?
    【解决方案2】:

    运算符左侧的表达式必须派生自要连接的“外部”事物,右侧的表达式必须派生自“内部”事物(正如您在对 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 &gt; a.w * b.z 这样的东西在 SQL 中很好,但在 LINQ 中不行),你只能基于显式投影之间的相等条件加入外表和内表。在我看来,这是一个非常不幸的设计决定,但它已从 LINQ 延续到 F#。

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多