1

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!

4
  • 1
    Honsetly, the code is close to be unreadable, at least on SO. I would transer the whole "where" clause to a separate function which returns a bool - that is way easier to understand and debug. Commented May 23, 2013 at 11:12
  • 4
    I'm nervous that you're mixing || and && without brackets - it's easy to get the wrong associations. Try bracketing it as you're expecting the logic to work. Commented May 23, 2013 at 11:13
  • Please provide sample input and expected output. Commented May 23, 2013 at 11:14
  • May I suggest that you need to overcome "primitive obsession". obj.strDateCode is a clear case of primitive obsession. Commented May 23, 2013 at 11:21

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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]))

Comments

3

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.

2 Comments

Your statement If any of Condition1, Condition2, or Condition3 are true, the entire predicate will return true is incorrect if the first 3 conditions are true it will evaluate the fourth condition. The first two short circuit if they are true while the third short circuits if it is false because it is on the left side of a && operator, not a || operator.
@juharr Thanks for pointing out my error. I corrected the response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.