如何使用多个where子句处理LINQ中的空值

时间:2013-06-05 13:54:55

标签: asp.net vb.net linq where-clause

我在where子句中有一个LINQ查询,其中包含多个值。 where子句中的值来自checkboxlist中的Filtering options。 Checkboxlist可以返回Null(或者例如是空字符串),这意味着我在查询中不需要where子句,因为在checkboxlist上选择none意味着选择all。我不知道如何编写一个可以处理的LINQ,所以我最终使用多个IF语句和多个查询,如下所示。我测试了它并且在where子句中使用2个参数正常工作。但实际上,我需要更多的参数传递给查询,并且有很多IF语句来完成这项工作会很麻烦。我如何在一个好的LINQ查询中处理它?<​​/ p>

Function FilterCol(ByVal col As List(Of ProductDetails), Optional SelectedCategory As List(Of String) = Nothing, Optional SelectedBrand As List(Of String) = Nothing) As List(Of ProductDetails)

    Dim strSelectedCategory  As String = String.Join(",", SelectedCategory .ToArray())
    Dim strSelectedBrand  As String = String.Join(",", SelectedBrand .ToArray())

    If strSelectedCategory  = "" And strSelectedBrand  = "" Then
        Return col
    ElseIf strSelectedCategory  = "" Then
        Dim res1 As IEnumerable(Of StatsDetails) = From x In col Where strSelectedBrand.Contains(x.Brand) Select x
        Return res1.ToList
    ElseIf strSelectedBrand  = "" Then
        Dim res2 As IEnumerable(Of StatsDetails) = From x In col Where strSelectedCategory.Contains(x.Category) Select x
        Return res2.ToList
    Else
        Dim res As IEnumerable(Of StatsDetails) = From x In col Where strSelectedCategory.Contains(x.Category) And strSelectedBrand.Contains(x.Brand) Select x
        Return res.ToList
    End If

End Function

3 个答案:

答案 0 :(得分:0)

如果您的LINQ查询有多个可变条件,请考虑使用Dynamic LINQ Library。它允许您根据提供的参数预先将条件组合成字符串变量,然后将该变量用作LINQ查询的条件 - 这类似于SQL Server中的动态SQL。

答案 1 :(得分:0)

使用扩展方法语法更容易。我不认为这样做是一个LINQ语句是一个好主意。

您可以做的是首先仅使用表格创建基本查询。我打算用C#来做,但翻译成VB并不复杂 - 我不想让你或我自己迷惑!

var baseQuery = col;

现在您已经拥有了基础表,您可以根据自己的条件开始添加数据。

if(condition1 == true)
{
    baseQuery = baseQuery.Where(this is your where condition);
}

if(condition2 == true)
{
    baseQuery = baseQuery.Where(this is another condition);
}

因此,您可以将Where链接在一起,以便根据条件缩小查询范围。

最后,使用ToList返回查询结果。这样可以避免您在条件中遇到的代码重复,并且更容易理解和维护。

答案 2 :(得分:0)

像这样使用lambda exp:

Dim FnValueExists = 
      Function(v As String, a As List(Of String)) a Is Nothing OrElse 
                                                  a.Count = 0 OrElse 
                                                  a.Contains(v)

然后在你的linq中,只测试下面的值:

Dim res As IEnumerable(Of StatsDetails) = 
                    From x In col 
                    Where FnValueExists(x.Category, SelectedCategory) And 
                          FnValueExists(x.Brand, SelectedBrand)
                    Select x

确定是否选择项x的主要代码是a Is Nothing OrElse a.Count = 0 OrElse a.Contains(v) lambda表达式中的FnValueExists行。

在上述情况下,如果SelectedCategory和/或SelectedBrand列表为Nothing或为空(Count = 0),或者包含该值,则仍会选择该项目。

因此,如果用户未选择任何类别,您可以将SelectedCategory设置为Nothing或仅设置为空列表,因此FnValueExists(x.Category, SelectedCategory)将始终返回true。