LINQ Where子句行为

时间:2014-05-05 18:51:03

标签: c# asp.net linq search

我正在尝试编写搜索例程,其中一部分包含以下代码:

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

由于我无法搜索字符串的位值,因此我使用三元运算符来评估它是否为真。如果是这样,我[手动]将字段名称转换为字符串,看看它是否包含搜索字符串。如果位值为false,我宁愿从WHERE子句中排除该行但无法提出任何聪明的想法,因此我使用IncidentID字段转换为包含Contains()方法的字符串作为填料

使用以下数据集作为示例:

+------------+-------------+--------------+-----------+
| IncidentID | ResultOther | BodyPartHead | IsDeleted |
+------------+-------------+--------------+-----------+
|          1 |           0 |            1 |         0 |
|          2 |           1 |            1 |         0 |
|          3 |           0 |            1 |         0 |
+------------+-------------+--------------+-----------+

问题是当searchValue等于“body”时,它只返回IncidentID 1和3,但是2也应该在那里。相反,如果searchValue等于“result”,它只会按预期返回IncidentID 2。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您有运营订单问题。 <{1}}(OR)在条件三元运算符之前进行评估。您需要用括号括起两个||操作:

OR

您的原始代码相当于:

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

(您也可以摆脱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)) ) 并使用== true代替!,但这些不会改变结果,只是整容变化)

答案 1 :(得分:1)

我相信你需要围绕内部? :语句进行调整,如下所示:

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

从描述您实际想要完成的内容开始,我认为以下简化会给您带来相同的结果:

var injurySearchList2 = (from i in injuryObj
                         where !i.IsDeleted 
                         && (
                             (i.ResultOther && "resultother".Contains(searchValue))
                          || (i.BodyPartHead  && "bodyparthead".Contains(searchValue))
                         )
                         select i.IncidentID).ToList();

答案 2 :(得分:1)

您需要在两个条件周围加上括号。第二个是第一个被包围到第一个,像这样:

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

应该是:

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