2013-05-08 110 views
5

我試圖從ODataQueryOptions中提取過濾器表達式,以便我可以在我的業務邏輯類中使用它。如何將OData過濾器轉換爲LINQ表達式?

public PageResult<Poco> Get(ODataQueryOptions odataQueryOptions) 
{ 
    Expression<Func<Poco, bool>> myExpression = ... // what do i do here? 

    var result = _myBusinessLogic.Search(myExpression); 
    return new PageResult<Poco>(result, null, null); 
} 

我看了看說明翻譯成查詢HQL here的博客,我認爲(至少我希望如此)這是什麼,我試圖做一個矯枉過正。

我基本上需要獲取Expression<Func<Poco, bool>>表單中的過濾器表達式。我試着玩ApplyTo(),但我不太明白。任何幫助讚賞。

回答

4

我們有一個適合您的需求的FilterBinder類,但不幸的是內部。但是你可以做一個簡單的技巧,以獲得$過濾器表達式的保持,

public static class ODataQueryOptionsExtensions 
{ 
    public static Expression ToExpression<TElement>(this FilterQueryOption filter) 
    { 
     IQueryable queryable = Enumerable.Empty<TElement>().AsQueryable(); 
     queryable = filter.ApplyTo(queryable, new ODataQuerySettings()); 
     return queryable.Expression; 
    } 
} 

在你的情況,你可以做,

public PageResult<Poco> Get(ODataQueryOptions odataQueryOptions) 
{ 
    Expression<Func<Poco, bool>> myExpression = odataQueryOptions.Filter.ToExpression<Poco>(); 

    var result = _myBusinessLogic.Search(myExpression); 
    return new PageResult<Poco>(result, null, null); 
} 

注意,該表達式包含看起來更像這樣, SOTests.Customer[].Where($it => conditional-expression)。所以,你可能不得不從lambda中提取這個條件表達式。

+1

謝謝,我最終做了類似的事情。看起來好像需要進行相當多的手術才能將過濾器表達式從ApplyTo-casting的結果中移除到MethodCallExpression,提取參數和操作數等。稍微擔心此代碼的長期穩定性。 – boris 2013-05-08 19:58:18

+0

我沒有將應用程序層(api)暴露給上下文,我想利用ODataQueryOptions和相關的類來在我自己的數據層中應用過濾器,分頁,導航等。 理想情況下,我希望能夠提取所有可以應用於查詢的表達式,並將這些表達式作爲參數傳遞給應用程序的較低層。 我到目前爲止的選項是通過ODataQueryOptions,但這會將我的業務和數據層耦合到數據,這是我不想要的。 你可能在GitHub上有一個例子可以幫助我嗎? – Manuel 2018-03-04 19:30:44