Reputation: 112
I’m attempting to write a search routine and part of it includes the following code:
string searchValue = Server.HtmlEncode(RadSearchBox.Text.ToLower());
var injurySearchList = (from i in injuryObj
where i.IsDeleted == false &&
(
i.ResultOther == true ? "ResultOther".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue)
|| i.BodyPartHead == true ? "BodyPartHead".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue)
)
select i.IncidentID).ToList();
Since I’m unable to search the bit values for a string, I use the ternary operator to evaluate if it’s true. If so, I [manually] convert the field name to a string and see if that contains the search string. If the bit value is false, I’d prefer to exclude that line from the WHERE clause but was unable to come up with any clever ideas, so I used the conversion of the IncidentID field to a string with a Contains() method as a filler.
Using the following dataset as an example:
+------------+-------------+--------------+-----------+
| IncidentID | ResultOther | BodyPartHead | IsDeleted |
+------------+-------------+--------------+-----------+
| 1 | 0 | 1 | 0 |
| 2 | 1 | 1 | 0 |
| 3 | 0 | 1 | 0 |
+------------+-------------+--------------+-----------+
The issue is when searchValue equals “body”, it’s only returning IncidentID 1 and 3, but 2 should be in there as well. Inversely, if searchValue equals “result”, it only returns IncidentID 2, as intended.
Any ideas?
Upvotes: 1
Views: 424
Reputation: 629
You need to put parentheses around the two conditions. The second one is getting wrapped up into the first, like this:
where i.IsDeleted == false &&
(
i.ResultOther == true ? "ResultOther".ToLower().Contains(searchValue) : (i.IncidentID.ToString().Contains(searchValue) || i.BodyPartHead == true ? "BodyPartHead".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue))
)
Should be:
where i.IsDeleted == false &&
(
(i.ResultOther == true ? "ResultOther".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue))
|| (i.BodyPartHead == true ? "BodyPartHead".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue))
)
Upvotes: 1
Reputation: 3907
I believe you need parantesis around the inner ? :
statements, like this:
var injurySearchList = (from i in injuryObj
where i.IsDeleted == false &&
(
(i.ResultOther == true
? "ResultOther".ToLower().Contains(searchValue)
: i.IncidentID.ToString().Contains(searchValue))
|| (i.BodyPartHead == true
? "BodyPartHead".ToLower().Contains(searchValue)
: i.IncidentID.ToString().Contains(searchValue))
)
select i.IncidentID).ToList();
From how you describe what you actually want to accomplish, I think the following simplification gives you the same results:
var injurySearchList2 = (from i in injuryObj
where !i.IsDeleted
&& (
(i.ResultOther && "resultother".Contains(searchValue))
|| (i.BodyPartHead && "bodyparthead".Contains(searchValue))
)
select i.IncidentID).ToList();
Upvotes: 1
Reputation: 152556
You have an order-of-operations issue. OR
(||
) is evaluated before the conditional ternary operator. You need to surround the two OR
operations with parentheses:
where i.IsDeleted == false &&
(
(i.ResultOther == true ? "ResultOther".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue))
|| (i.BodyPartHead == true ? "BodyPartHead".ToLower().Contains(searchValue) : i.IncidentID.ToString().Contains(searchValue))
)
You original code is equivalent to:
where i.IsDeleted == false &&
(
i.ResultOther == true
? "ResultOther".ToLower().Contains(searchValue)
: (i.IncidentID.ToString().Contains(searchValue)) || (i.BodyPartHead == true)
? "BodyPartHead".ToLower().Contains(searchValue)
: i.IncidentID.ToString().Contains(searchValue))
)
(you can also get rid of == true
and use !
instead of == false
, but those don't change the results and are just cosmetic changes)
Upvotes: 1