传递nhibernate查询的表达式

时间:2016-01-10 12:25:55

标签: vb.net nhibernate

我需要在表达式作为函数参数的地方给出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而没有任何细节。

是否可以在函数范围之外提供表达式?

2 个答案:

答案 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”非常有用。