我需要在表达式作为函数参数的地方给出nhibernate:
Public Function FindByCriteria(customCriteria As Expression(Of Func(Of Transaction, Boolean))) As IList(Of Transaction)
Dim query = GetBasicQuery()
query = query.Where(customCriteria)
return query.ToList()
End Function
通过在lambda表达式中设置函数的地址来调用方法,因为表达式在VB.NET中不支持多行
Public Sub SearchService(criteria As SearchCriteria)
_transactionService.FindByCriteria(Function(x) BuildCustomCriteriaForCustomer(x, criteria))
...
End Sub
然后在BuildCustomCriteriaForCustomer中我使用x和标准。
然而,这似乎不起作用,它只是抛出NotSupportedException而没有任何细节。
是否可以在函数范围之外提供表达式?
答案 0 :(得分:2)
您必须构建一个可以转换为sql的有效表达式树。你的函数BuildCustomCriteriaForCustomer
不能翻译成sql。因此,此函数必须将SearchCriteria转换为表达式树。
我假设你的SearchCriteria
是一个带有属性名称和枚举的模型。使用NhibernateSession.CreateCriteria()
并从SearchCriteria创建ICriterion
个对象来添加它会更容易。
答案 1 :(得分:1)
构建动态Linq查询以与Session.Query()
一起使用是完全可以的,但是你不能指望NHibernate理解BuildCustomCriteriaForCustomer()
的编译代码。你必须确保整个 critera是一个LINQ表达式。
您展示的代码相当于:
Dim query = GetBasicQuery()
query = query.Where(Function(x) BuildCustomCriteriaForCustomer(x, criteria))
当然这不起作用,因为NHibernate不知道BuildCustomCriteriaForCustomer()
做了什么(NHibernate可以用这些知识扩展,但在这种情况下无济于事。
相反,请执行:
Public Function BuildCustomCriteriaForCustomer(criteria As SearchCriteria)
As Expression(Of Func(Of Transaction, Boolean))
Dim f as Expression(Of Func(Of Transaction, Boolean))
x = Function (x as Customer)
something
EndFunction
return x
EndFunction
这将使编译器以NHibernate可以分析的格式保留您的LINQ表达式。
此外,PredicateBuilder对于向LINQ表达式添加动态数量的“and”和“or”非常有用。