Panu Oksala
Panu Oksala

Reputation: 3438

Passing where expression for nhibernate query

I need to give nhibernate where expression as a function parameter:

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

Method is called by setting address of function inside lambda expression, because expressions doesn't support multiline in VB.NET

Public Sub SearchService(criteria As SearchCriteria)

_transactionService.FindByCriteria(Function(x) BuildCustomCriteriaForCustomer(x, criteria)) 
...
End Sub

Then inside BuildCustomCriteriaForCustomer I'm using x and criteria.

However this doesn't seem to work, it just throws NotSupportedException without any details.

Is it possible to give expressions outside of function scope?

Upvotes: 0

Views: 369

Answers (2)

Oskar Berggren
Oskar Berggren

Reputation: 5629

It is perfectly fine to build dynamic Linq queries for use with Session.Query() but you can't expect NHibernate to understand the compiled code of BuildCustomCriteriaForCustomer(). You have to make sure the entire critera is a LINQ expression.

The code you have shown is equivalent to:

Dim query = GetBasicQuery()
query = query.Where(Function(x) BuildCustomCriteriaForCustomer(x, criteria))

Which of course doesn't work, because NHibernate doesn't know what BuildCustomCriteriaForCustomer() does (NHibernate can be extended with that knowledge, but wouldn't help in this situation.

Instead, do:

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

This will make the compiler preserve your LINQ expression in a format that NHibernate can analyze.

Also, PredicateBuilder is useful to add a dynamic number of "and" and "or" to a LINQ expression.

Upvotes: 1

Firo
Firo

Reputation: 30803

You have to build a valid expression tree which can be translated to sql. Your function BuildCustomCriteriaForCustomer is not translatable to sql. So this function has to convert the SearchCriteria to an Expression tree.

I assume your SearchCriteria is a model with property names and enums. It would be much easier to use NhibernateSession.CreateCriteria() and create ICriterion objects out of your SearchCriteria to add to it.

Upvotes: 2

Related Questions