2015-11-17 24 views
0

我在写一些linq查询,我想知道是否有任何区别的顺序的条款。 例如:它有什么区别写在顶部或底部的where子句LINQ

lstParam.Where(p => p).Select(p => p).ToList<Type>(); 

lstParam.Select(p => p).Where(p => p).ToList<Type>(); 

通过差异我的意思是在性能上还是在发展的标准。 任何人都可以给出一个简短的解释吗?

+2

这取决于你需要做的第一...变换数据或过滤器数据。过滤通常在序列中较早执行的更好,因为它在后面的操作中导致更少的记录被操作。但从逻辑上讲,这并不总是一种选择。 – David

+2

@ M.kazemAkhgary“选择”什么都不做,但“Where”不是。如果他传递了'p => true' *,那么*就什么也不做。目前它需要是一系列的布尔运算符,它会产生所有那些“真实的”。 – Servy

+0

糟糕。是的,你是对的@Servy但是我的主要观点是先过滤更好,但你可能无法总是直接过滤。 –

回答

1

如果您的.Where取决于在.Select中所做的更改,那么它必须遵循(1)。如果您的.Select会在与.Where不匹配的记录上抛出异常,那么必须先到达(2)。如果您的.Where想要使用未通过.Select的属性,那么.Where必须先执行(3)。

你可以做多。选择和。哪里还有...

var a=x.Select(p=>p).Where(p=>p).Select(p=>p); 

在一般情况下,如果为了不完成重要,那么.Where首先是,如果事情没有得到优化更快。这是因为一个新的对象不需要为.Where失败的任何东西实例化。也就是说,在绝大多数在数​​据库上使用IQueryable的情况下,它根本没有区别(速度方面,如果顺序不重要)。

实施例1:

var result=x.Select(p=>new Person { Name=p.First+" "+p.Last }) 
    .Where(p=>!String.IsNullOrEmpty(p.Name)); // works 
var result=x.Where(p=>!String.IsNullOrEmpty(p.Name)) 
    .Select(p=>new Person { Name=p.First+" "+p.Last }); // Does not work 

实施例2:

var result=x.Select(x=>new {DollarsPerDay=x.Dollars/x.Day}) 
    .Where(x=>x.Day>0); // may throw exception when day == 0 
var result=x.Where(x=>x.Day>0); 
    .Select(x=>new {DollarsPerDay=x.Dollars/x.Day}) // works 

实施例3:

var result=x.Select(p=>new Person { Name=p.First+" "+p.Last }) 
    .Where(p=>p.Age>18); // Doesn't work 
var result=x.Where(p=>p.Age>18) 
    .Select(p=>new Person { Name=p.First+" "+p.Last }); // Works 
+0

谢谢@Robert McKee。这是一个相当的解释。 –

1

Select中的实体投影不起任何作用。完全删除它不会改变程序(除了使它更快捷),并且在查询中添加额外的这种投影,在任何时候,也不会做任何事情(除了使程序慢一点),所以不管你的没有任何操作是在无关的地方之前或之后。

在这两种情况下,表现不同的情况都不太可能发生,但如果您确实在意,只需将其彻底删除即可。

+1

在我给这里的例子没有区别,但我有一些更复杂的查询,我用Select子句来挂载输出对象。 我喜欢:选择(p => {ID = p.ID}) –

+0

@KingClauber我无法评论任何两个未知操作改变顺序的所有可能影响。有各种各样的事情可能发生,而且没有办法描述所有这些事情。 – Servy

相关问题