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 中我们有 Or
和 OrElse
,你应该更喜欢使用 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:我没测试过。
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 中我们有 Or
和 OrElse
,你应该更喜欢使用 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:我没测试过。