2013-02-28 62 views
1

里面我有两个类:使用表达式树的另一种表达树

class Foo 
{ 
    string Name 
} 

class Bar 
{ 
    IList<Foo> Foos; 
} 

而下面的表达式树:

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

在NHibernate中我可以这样写:

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

它的工作原理。

虽然,我不能写:

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

这是一个编译错误,因为IEnumerable.Any的不期望Expression<TDelegate>

是否有可能实现?我是否必须重写fooFilters Expression,或者有其他方法吗?我对表达式树操作知之甚少,任何人都可以将我指向正确的方向吗?

我正在使用框架3.5,为此。

+0

的问题是,你的类'Bar'被定义为持有'IList的'。你不能像这样互换'IQueryable '和'IEnumerable '。 – 2013-03-01 06:32:27

+0

你试过Session.Query ().Where(bar => bar.Foos.Any(fooFilters.Compile())); ? – jbl 2013-03-01 09:46:53

+0

@jbl,因为NHibernate(和其他ORM,AFAIK)无法处理已编译的lambdas,所以直接调用'Compile'会在运行时引发异常。在svick答案中的LINQKit让我调用Compile,并在将表达式返回给NHibernate之前将它去掉。 – Andre 2013-03-01 21:44:26

回答

3

您可以使用Invoke()AsExpandable()LINQKit来执行此操作。

有了它,你的代码应该是这样的:

Session.Query<Bar>().AsExpandable() 
     .Where(bar => bar.Foos.Any(foo => fooFilters.Invoke(foo))) 
+0

谢谢,它工作。除了我使用'fooFilters.Compile()'而不是'Invoke'(和LINQKit条带) – Andre 2013-03-01 21:40:43