shanmugharaj
shanmugharaj

Reputation: 3924

How to use array in where condition in Linq queries

This is my linq query.

var data =
  (from obj in lstEventsDataForGrid
   where obj.strDateCode.Contains(thisWeekend[0] == null ? "" : thisWeekend[0])
         || obj.strDateCode.Contains(thisWeekend[1] == null ? "$" : thisWeekend[1])
         || obj.strDateCode.Contains(thisWeekend[2] == null ? "$" : thisWeekend[2])
            && strArr.Contains(obj.strEventType.ToString().ToUpper())
   orderby obj.dtmStartDate ascending
   select obj).GroupBy(x => x.strEventCode)
              .Select(y => y.First()).ToArray();

Expected Result

It should not come whether the strEventType is not in the strArr.

But it is coming even that type is not in the array.

Issue I noticed is if I remove one where condition i.e that obj.strDateCode.Contains(...) the other condition is working.

Where am I going wrong? Please suggest something!

Upvotes: 1

Views: 1254

Answers (3)

drf
drf

Reputation: 8709

Your where predicate contains an error:

obj.strDateCode.Contains(thisWeekend[0] == null ? "" : thisWeekend[0])
|| obj.strDateCode.Contains(thisWeekend[1] == null ? "$" : thisWeekend[1])
|| obj.strDateCode.Contains(thisWeekend[2] == null ? "$" : thisWeekend[2]) 
&& strArr.Contains(obj.strEventType.ToString().ToUpper())

This is an expression of the form:

where Condition1 || Condition2 || Condition3 && Condition4.

In C#, the && operator takes precedence over the || operator, so this is equivalent to

where Condition1 || Condition2 || (Condition3 && Condition4).

In this situation, Condition4 is only evaluated if Condition3 is true. If Condition1 or Condition2 are true, the entire predicate will return true and the remainder of the expression will short-circuit.

What you probably intended was:

where (Condition1 || Condition2 || Condition3) && Condition4

Or, extended to your example:

(obj.strDateCode.Contains(thisWeekend[0] == null ? "" : thisWeekend[0])
 || obj.strDateCode.Contains(thisWeekend[1] == null ? "$" : thisWeekend[1])
 || obj.strDateCode.Contains(thisWeekend[2] == null ? "$" : thisWeekend[2]) 
) && strArr.Contains(obj.strEventType.ToString().ToUpper())

This will ensure that an obj will not be returned if it is not contained within strArr,
which your question indicates is the required result.

Upvotes: 3

Alex
Alex

Reputation: 23290

I rewrote your query using null-coalesce operators to make it more readable. I also added line numbers to point out what I think is wrong here:

1.     var data = (
2.         from obj in lstEventsDataForGrid
3.         where obj.strDateCode.Contains(thisWeekend[0] ?? "") ||
4.              obj.strDateCode.Contains(thisWeekend[1] ?? "$") ||
5.              obj.strDateCode.Contains(thisWeekend[2] ?? "$") &&
6.              strArr.Contains(obj.strEventType.ToString().ToUpper())
7.         orderby obj.dtmStartDate ascending
8.         select obj
9.         ).GroupBy(x => x.strEventCode).Select(y => y.First()).ToArray();

You need to change the following lines:

3.         where (obj.strDateCode ...          // add '('
5.         ... thisWeekend[2] ?? "$")) &&      // add ')'

This way, your && will overpower the rest of the conditions.

Upvotes: 3

Colm Prunty
Colm Prunty

Reputation: 1620

I think you're missing some parentheses. Do you mean to treat the three || conditions as one option? As in

where (A || B || C) && D

Try put one after where here:

where (obj.strDateCode.Contains(thisWeekend[0]

and a second one here:

: thisWeekend[2]))

Upvotes: 3

Related Questions