使用LINQ在'where'语句中动态变化的条件数

时间:2010-02-03 17:38:03

标签: sql vb.net linq where-clause

我正在使用LINQ(在mvc中)开发我的第一个项目,所以我可能会错过一些非常简单的事情。然而,一天的搜索和实验并没有发现任何有效的东西,因此是帖子。

我正在尝试编写LINQ查询(Linq to SQL),该查询将在由OR或AND分隔的where语句中包含多个条件。在运行时,我们不知道查询中有多少条件。这适用于搜索过滤器控件,用户可以在其中选择要过滤的多个条件。

select * from table
where table.col = 1 
    OR table.col = 2
    OR table.col = 7
    .... 'number of other conditions

在我循环遍历所有条件之前,我将SQL查询构造为字符串。但是,看起来在LINQ中应该有一个很好的方法。 我曾尝试使用表达式树,但目前它们似乎有点过头了。另一个想法是在where语句中执行lambda函数,如下所示:

For Each value In values
    matchingRows = matchingRows.Where(Function(row) row.col = value)

但是,这仅适用于AND条件。我该怎么做OR?

3 个答案:

答案 0 :(得分:2)

我会使用PredicateBuilder。它使动态WHERE子句变得非常容易。

答案 1 :(得分:1)

AND很简单 - 您只需在循环中调用Where即可。 OR比较棘手。你提到SQL,所以我假设这就像LINQ-to-SQL,在这种情况下,我发现这样做的一种方法是在运行时构建自定义Expression树 - like so(例如C#,但是如果你需要帮助将它翻译成VB,请告诉我;我的VB不再太棒了,所以我先让你试试......你可能比我写VB更能读C#)。

不幸的是,这不适用于3.5SP1中的EF(由于Expression.Invoke),但我相信这在4.0中是固定的。

答案 2 :(得分:0)

这样的东西应该有用(原谅我的VB):

Expression(Of Func(Of Something, Boolean)) filter = Nothing
ParameterExpression rowParam = Expression.Parameter("row", CType(Something))

For Each value In values
    filterPart = Expression.Equal( _
        Expression.Property(rowParam, "col"), _
        Expression.Constant(value)))
    If filter Is Nothing Then
        filter = filterPart 
    Else
        filter = Expression.OrElse(filter, filterPart)
    End If
Next

If newPredicate IsNot Nothing Then
    matchingRows = matchingRows.Where( _
        Expression.Lambda(Of Func(Of SomeType, Boolean))(filter, rowParam))
End If

不能保证,我的VB有点生锈: - )

但如果你想要做的事情比AndOr更复杂,那么PredicateBuilder可能是更好的解决方案。