5

I query my Database using NHibernate. Now I need to restrict the data being selected using a Predicate. So far I found out (Google driven development at its best) that something like this is possible using Expressions and NHibernate.Linq.

Here's what I tried:

public IList<Bestellung> GetAll(Predicate<Order> predicate)
{
    Expression<Func<Order, bool>> restriction = x => predicate(x);
    ISession session = SessionService.GetSession();
    IList<Order> bestellungen = session.Query<Order>()
                        .Where(restriction).ToList();
    return bestellungen;
}

This results in Unable to cast object of type 'NHibernate.Hql.Ast.HqlCast' to type 'NHibernate.Hql.Ast.HqlBooleanExpression'. Just a quickie to check where it sucks: Change the first line of the method body to

Expression<Func<Order, bool>> restriction = x => x.Id!=1;

with the stunning result that everything works fine.

How can I get my Predicate executed in the expression?

Sebastian Edelmeier
  • 4,095
  • 3
  • 39
  • 60

1 Answers1

6

You can't - at least not easily. NHibernate (as EF and LINQ to SQL) interpret the expression and convert it to SQL. NHibernate simply doesn't know how to translate your predicate to SQL.

One way to achieve it would be to replace the Predicate<T> itself with an Expression<Func<T, bool>>:

public IList<Bestellung> GetAll(Expression<Func<Order, bool>> restriction)
{
    ISession session = SessionService.GetSession();
    IList<Order> bestellungen = session.Query<Order>()
                        .Where(restriction).ToList();
    return bestellungen;
}

Important:
Your code that calls this method would still look the same as before:

var orders = GetAll(x => x.Id != 1);
Community
  • 1
  • 1
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Thanks, Daniel. I have read it was working with an Expression> from other sources as well, I just thought there was a way of using what I had - now I have refactored my API to use the Expression instead! Thanks again! – Sebastian Edelmeier Mar 28 '12 at 12:28