2009-11-04 34 views
7

它看起来像我可以写一个where x.a==1 && x.b==1作为LINQ-to-SQL中多个where子句和&&运算符有什么区别?

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

据我了解后者转化成了.Where(x => x.a == 1).Where(x => x.b ==1),但这是如何转化为DB?在优化方面哪个更好?我总是可以从分析器中查看执行的查询,但这不会是泛化,而更像是单一的经验观察,我不想依赖它。

使用带反射器的System.Linq命名空间是另一种选择,但这样我们就错过了将很多人花在同一件事上的机会。如果我没有得到任何答案,我会做。

+2

几乎重复http://stackoverflow.com/questions/1648730/when-using-linq-what-is-the-difference-between-and-multiple-where-clauses – 2009-11-04 11:27:20

+0

我没有发现在我的搜索,但无论如何,这是LINQ到SQL的具体情况。 – 2009-11-04 11:34:23

+0

对LINQ到对象的影响将是显而易见的,但LINQ到SQL尚不清楚。 – 2009-11-04 11:35:14

回答

7

好的,这是我的发现经过Reflector输出一段时间后。 LINQ到对象使用WhereArrayIteratorWhereListIterator当它导致几乎表现得像& &运营商结合起来,连续where谓词,但不能作为确切:

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

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

但是,当您使用连续的Where子句时,会有轻微的性能损失,至少源于非JITted 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到对象示例那样受到惩罚。

编辑:我见过多个where语句导致SQL服务器上的嵌套子查询的实例。我认为,只要能够保证安全,就坚持单个地方发言是更好的办法。

2

这是由LINQ to SQL在这里做正确的事情。我期望它将两个“where”子句转换为一个SQL子句,两个部分用“AND”连接起来。

尝试这两种 - 但我非常怀疑你会看到生成的SQL中的任何区别。

IMO你应该总是看看生成的SQL的任何非平凡的东西,但LINQ的工作方式肯定是鼓励你通过小条款构建一个大的查询 - 所以我真的期望它只是工作。

+0

它看起来像,谢谢! – 2009-11-08 14:53:01

2

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

2

的代码:

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

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

为C#反正语法糖。这将汇编为

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

就像你猜它可能会一个LINQ方法链,让我真的无疑有在生成的SQL任何区别。尝试使用Jetbrains的Resharper工具 - 它甚至提供智能感知功能,可让您选择在两者之间进行自动转换,从而节省您重新编写测试的时间。

我的首选是将非常简单的查询写成方法链(例如,只有一个集合/表涉及并且没有连接)以及更复杂的Linq Sugar语法。

+0

显然他们不是很相同,请参阅我的答案。 – 2009-11-08 14:51:46

相关问题