Question

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?

Was it helpful?

Solution

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)

OTHER TIPS

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();

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))
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top