2013-02-28 63 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