2011-09-27 96 views
1

在这个查询对数据表我试图做一些条件过滤。 只有当索引存在时,才能对时间带(索引N)进行检查。 (基码只有三个项字段中,我它们转换为一个简单的列表)Vb.net有条件的linq查询

Dim res As DataTable = 
    (
     From dr As DataRow In dtTimedRow.AsEnumerable() 
     Select dr 
     Where 
     (TimeBands.Count > 0 AndAlso 
     dr.Field(Of Short)(fldStarttime) >= TimeBands(0).StartTime 
     And dr.Field(Of Short)(fldStarttime) <= TimeBands(0).EndTime 
     ) Or 
     (TimeBands.Count > 1 AndAlso 
     dr.Field(Of Short)(fldStarttime) >= TimeBands(1).StartTime 
     And dr.Field(Of Short)(fldStarttime) <= TimeBands(1).EndTime 
     ) Or 
     (TimeBands.Count > 2 AndAlso 
     dr.Field(Of Short)(fldStarttime) >= TimeBands(2).StartTime 
     And dr.Field(Of Short)(fldStarttime) <= TimeBands(2).EndTime) 
    ).CopyToDataTable() 

上面的代码触发异常如果计数= 1它执行旁边imeBands.Count代码> 1它不应该。这个代码的正确解决方案是什么?

同时,我添加了一个简单的过滤功能。

+0

抛出哪个异常? –

回答

3

的问题是,使用时And你应该用AndAlso

TimeBands.Count> 2
AndAlso dr.Field(短)(fldStarttime)> = TimeBands(2) .StartTime(= COND1)
dr.Field(短)(fldStarttime)< = TimeBands(2).EndTime(= COND2)

由于AndAndAlsohave the same operator precedence,这是评价左到右如下:

(TimeBands.Count> 2 AndAlso COND1) COND2

And不短期电路,即表达式(cond2)的右侧总是被忽略,当TimeBands.Count <= 2时,产生一个例外。所有And的变化对AndAlso秒,你应该罚款:

TimeBands.Count> 2 AndAlso COND1 AndAlso COND2

另一种方法是把括号是这样的:

TimeBands.Count> 2 AndAlso(COND1 cond2)

但这只是在浪费性能。由于cond1和cond2没有副作用,所以没有理由避免短路。出于同样的原因,我还建议将您的Or更改为短路变体OrElse

+1

你打败了我!我正在建议这个同样的事情。 –

+0

我自己应该看到那个 – CodingBarfield