0

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?

2
  • Looks a lot like the "abstract the ORM Anti-Pattern" to me. Why not creating a Public Function FindBySearchCriteria(customCriteria As SearchCriteria) As IList(Of Transaction) in your transactionService? Commented Jan 12, 2016 at 12:52
  • customCriteria contains two fields which are very customer specific and I dont want to pollute my search service with customer specific fields. Commented Jan 12, 2016 at 15:44

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes SearchCriteria is model with property names and enums. I will try that CreateCriteria() approach and if I get it working I will post some code and approve this answer.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.