1

I have two classes:

class Foo 
{
    string Name
}

class Bar
{
    IList<Foo> Foos;
}

And the following expression tree:

var fooFilters = (Expression<Func<Foo, bool>>)(foo => foo.Name == "baz");

In NHibernate I can write:

Session.Query<Bar>().Where(bar => bar.Foos.Any(foo => foo.Name == "baz"));

And it works.

Although, I can't write:

Session.Query<Bar>().Where(bar => bar.Foos.Any(fooFilters)); 

It's a compilation error, as IEnumerable.Any does not expect an Expression<TDelegate>.

Is it possible to achieve? Do I have to rewrite the fooFilters Expression, or is there another way?

I have very little knowledge in expression tree manipulation, can anyone point me to the right direction?

I'm using framework 3.5, for that matters.

svick
  • 236,525
  • 50
  • 385
  • 514
Ortiga
  • 8,455
  • 5
  • 42
  • 71
  • The problem is that your class `Bar` is defined to hold an `IList`. You can't really mix `IQueryable` and `IEnumerable` interchangeably like that. – Jeff Mercado Mar 01 '13 at 06:32
  • Have you tried Session.Query().Where(bar => bar.Foos.Any(fooFilters.Compile())); ? – jbl Mar 01 '13 at 09:46
  • @jbl, calling `Compile` directly throws an exception at runtime, since NHibernate (and others ORM, AFAIK) can't deal with compiled lambdas. LINQKit in svick answer let me call Compile, and strips it out before returning the Expression to NHibernate. – Ortiga Mar 01 '13 at 21:44
  • Of course. I should have thought that's just the point for using Expression instead of jsut Func :-) Thx for the follow-up – jbl Mar 04 '13 at 07:56

1 Answers1

3

You can use Invoke() and AsExpandable() from LINQKit to do this.

With it, your code would look like this:

Session.Query<Bar>().AsExpandable()
       .Where(bar => bar.Foos.Any(foo => fooFilters.Invoke(foo)))
svick
  • 236,525
  • 50
  • 385
  • 514
  • Thanks, it worked. Except that I used `fooFilters.Compile()` instead of `Invoke` (and LINQKit strips that out) – Ortiga Mar 01 '13 at 21:40