代码之家  ›  专栏  ›  技术社区  ›  Sedat Kapanoglu johnnywhoop

linq to sql中的多个where子句和&&operator有什么区别?

  •  8
  • Sedat Kapanoglu johnnywhoop  · 技术社区  · 15 年前

    看起来我可以写一个 where x.a==1 && x.b==1 作为

    where x.a==1
    where x.b==1
    

    据我所知,后者变成 .Where(x => x.a == 1).Where(x => x.b ==1) ,但如何将其转换为db?在优化方面哪个更好?我总是可以从profiler中查看执行的查询,但这几乎不是一个泛化,而是更像一个单一的经验观察,我不想依赖它。

    使用Reflector浏览system.linq名称空间是另一种选择,但是我们会错过这样一个机会,那就是节省很多人的时间。如果我不知道答案,我就去做。

    4 回复  |  直到 11 年前
        1
  •  8
  •   Sedat Kapanoglu johnnywhoop    11 年前

    好的,这是我在对反射镜输出进行一段时间后的发现。Linq to对象组合连续 where 使用时使用谓词 WhereArrayIterator WhereListIterator 使其几乎表现得像运营商,但不完全是:

    当你使用 x.a==1 && x.b==1 WHERE子句转换为 Func<TSource, bool> 看起来像这样:

    bool daspredicate(TSource x)
    {
        return x.a==1 && x.b==1
    }
    

    但是,当您使用连续的where子句时,会有轻微的性能损失,至少从非抖动的il方面来说是这样。下面是代码组合后的外观:

    bool predicate1(TSource x)
    {
         return x.a==1;
    }
    bool predicate2(TSource x)
    {
         return x.b==1;
    }
    bool daspredicate(TSource x)
    {
        return predicate1(x) && predicate2(x);
    }
    

    如您所见,这涉及到额外的函数调用开销。这可能非常昂贵,除非JIT引入函数。我相信它在这方面做得很好,但是我们现在知道,如果我们自己结合我们的where语句,JIT的工作会变得容易得多,除非必要。

    但在SQL方面,查询是相同的。即使在执行之前,调试器也会将查询对象计算为同一个SQL语句。在Linq名称空间中我不能走得太远,因为事情看起来更复杂,但是由于查询是相同的,所以不应该像上面的Linq to对象示例那样受到惩罚。

    编辑:我看到过一些实例,其中多个WHERE语句会导致SQL Server上的嵌套子查询。我认为最好还是坚持单一的where语句,只要你能安全的话。

        2
  •  3
  •   Jon Skeet    15 年前

    在这里做正确的事情取决于Linq to SQL。我希望它将两个“where”子句转换为一个SQL子句,两个部分用“and”连接在一起。

    两者都试一下-但我非常怀疑您是否会看到生成的SQL中有任何不同。

    在我看来,对于任何重要的事情,您都应该查看生成的SQL,但是LINQ的工作方式是肯定的。 鼓励 您可以用小子句组成一个大查询,所以我真的希望它能正常工作。

        3
  •  2
  •   KristoferA    15 年前

    DB侧,它们是相同的。这只是LinqToSQL可组合的副作用(即,您可以从一个查询开始,然后向其添加其他条件、更改投影等)。

        4
  •  2
  •   Neil Fenwick    15 年前

    代码:

    where x.a==1
    where x.b==1
    

    where x.a==1 && x.b==1
    

    对C来说是句法上的糖分。它将编译为

    Where(...).Where(...)
    

    正如你所猜测的那样,我 真的? 怀疑生成的SQL中是否存在任何差异。尝试使用像JetBrains的Resharper这样的工具-它甚至提供了IntelliSense,让您可以选择在两者之间自动转换,以节省重新编写测试的时间。

    我的偏好是将真正简单的查询编写为方法链(例如,只涉及一个集合/表,没有连接)以及在更具表现力的LinqSugar语法中更复杂的任何查询。