Fluent、NHibernate 和 PredicateBuilder

Fluent, NHibernate, and PredicateBuilder

Fluent v1.4,NHibernate v4.0.2.4000,SQL服务器

我看到一些帖子在 NHibernate v3 中不评估带有嵌套 Lambda 表达式的 Predicate Builder。难道v4也有这个问题?

Public Function TestingWorldQuery() As List(Of EmployeeView)
    Dim EmpView = From q In m_Session.Query(Of EmployeeView)() 
    Dim expr = PredicateBuilder.False(Of EmployeeView)()
    For Each _opco In {"AGRI", "CORP", "FOODS"}
        Dim opco As String = _opco
        expr = expr.Or(Function(x) x.OpCoOrgId = opco)
    Next
    EmpView = EmpView.Where(expr)
    Return EmpView.ToList
End Function

Unable to cast object of type 'NHibernate.Hql.Ast.HqlBitwiseOr' to type 'NHibernate.Hql.Ast.HqlBooleanExpression'


更正 -- 根据 Felipe 的建议,我修改了 VB.NET PredicateBuilder 代码以使用 OrElse。我的代码现在可以工作了。

Imports System.Linq.Expressions

Public Module PredicateBuilder
    Public Function [True](Of T)() As Expression(Of Func(Of T, Boolean))
        Return Function(f) True
    End Function

    Public Function [False](Of T)() As Expression(Of Func(Of T, Boolean))
        Return Function(f) False
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function [OrElse](Of T)(ByVal expr1 As Expression(Of Func(Of T, Boolean)), ByVal expr2 As Expression(Of Func(Of T, Boolean))) As Expression(Of Func(Of T, Boolean))
        Dim invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast(Of Expression)())
        Return Expression.Lambda(Of Func(Of T, Boolean))(Expression.[OrElse](expr1.Body, invokedExpr), expr1.Parameters)
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function [AndAlso](Of T)(ByVal expr1 As Expression(Of Func(Of T, Boolean)), ByVal expr2 As Expression(Of Func(Of T, Boolean))) As Expression(Of Func(Of T, Boolean))
        Dim invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast(Of Expression)())
        Return Expression.Lambda(Of Func(Of T, Boolean))(Expression.[AndAlso](expr1.Body, invokedExpr), expr1.Parameters)
    End Function
End Module

在 VB.Net 中我们有 OrOrElse,你应该更喜欢使用 OrElse 而不是 Or 因为 Or 是按位的。查看您拥有的 PredicateBuilder,看看您使用的是 Expression.Or 还是 Expression.OrElse。如有必要,将其更改为 OrElse。就像在 C# 中 | 用于 Or|| 用于 OrElse.

您可以尝试使用 Contains 方法,它将生成 IN sql 语句而不是 Or。试试这个:

Public Function TestingWorldQuery() As List(Of EmployeeView)

   Return m_Session.Query(Of EmployeeView)().Where(Function(x) {"AGRI", "CORP", "FOODS"}.Contains(x.OpCoOrgId)).ToList()

End Function

Obs:我没测试过。