2016-07-27 31 views
0

我與一個過濾方法主要是通用的應用程序工作使用DynamicLinq:實體框架:在一般的過濾器的方法

​​

這裏是正在傳遞的過濾對象:

{ 
    Field: "Header.Title", 
    Operator: "contains", 
    Value: "asdf" 
} 

我有一個操作符的開關(包含,<,>,==等)來處理每一個不同的,但我將只關注「包含」這個例子。

被傳入的「查詢」變量是一個通用的接口列表,這是一個我所有200個實體繼承的接口。我甚至沒有從這個命名空間訪問實體類型的權限。

在此示例中,「query」參數是實體「Page」的IQueryable。 DynamicLinq的一個典型的例子爲包含將是以下幾點:

Expression<Func<Page, bool>> exp = l => l.Contains(filter.Value); 
query = query.Where("@0(it)", exp); 

然而,我的應用程序,這部分不是強類型的,我的域名不知道什麼是「頁」是,而是它使用繼承IDataBaseEntity作爲第一種類型的Func <。我收到一個異常,因爲「IDataBaseEntity」類型中存在「沒有屬性或字段'標題'」。我嘗試了其他各種選擇,但最終成爲主要問題。

注:我需要保持這是一個IQueryable,並且不希望在任何時候因爲性能原因將它變成IEnumerable。該查詢旨在僅在過濾,排序和分頁後運行(.AsEnumerable())。

是否有可能在命名空間中對接口類型運行動態LINQ針對IQueryable,該接口類型對我的實際實體類型一無所知?

回答

0

如何根本不使用接口 - 動態Linq無論如何都是遲到的。您可以在IQueryable<T>上應用動態Where,結果將爲IQueryable<T>

只要你能正確生成字符串斷言,下面應該工作:

query = query.Where("Header.Title.Contains(@0)", filter.Value); 
+0

啊感謝。這看起來是90%的正確答案,所以我會將其標記爲正確的。對於閱讀這篇文章的其他人來說,一些注意事項是:而不是「T:IDataBaseEntity」,方法類型需要是「T:class」,否則如果你有強類型查詢並試圖以.OfType結尾。要通過編譯,您將在運行時獲得EF複雜/原始異常。 我也最終使用LinqKit的query.AsExpandable()來避免「LINQ to Entities不支持LINQ表達式節點類型'Invoke'」。不確定是否存在AsExpandable的性能問題,或者是否有其他解決方法。 –