In this query against a datatable i’m trying to do some conditional filtering.
The check against Timeband(index N) should only be done when the Index exists. (the base code only had three item fields, i’ve converted them to a simple list)
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()
The above code triggers an Exception if the count = 1. It executes the code next to imeBands.Count > 1 which it should not. What would be the correct solution for this code.
In the mean time i’ve added a simple filter function.
The problem is that you use
Andwhen you should be usingAndAlso:Since
AndandAndAlsohave the same operator precedence, this is evaluated left-to-right as follows:Anddoes not short-circuit, i.e., the right-hand side of the expression (cond2) is always evaulated, yielding an exception whenTimeBands.Count <= 2. Change all yourAnds toAndAlsos, and you should be fine:An alternative would be to put parenthesis like this:
but that’s just wasting performance. Since cond1 and cond2 don’t have side effects, there’s no reason to avoid short-circuiting. For the same reasons, I recommend to also change your
Ors to the short-circuiting variantOrElse.