背景
我需要能夠建立一個.INCLUDE該過濾的結果,到或特定日期之前創建的記錄。我不會知道原始LINQ語句中的對象的類型,我會找到它們(通過大量的箍環,但那是行得通的)。動態構建包括與當過濾器
我有對象的這樣一個圖:
A -> Ac
/\
Bc <- B \
/ \
Cc <- C D -> Dc
對象Ac
,Bc
,Cc
,並Dc
都動態地發現(也就是寫原來的LINQ當開發者沒有鍵入這些關係聲明)。然後需要將它們添加到IQueryable表達式中,並且只返回特定DateTime的值。
到目前爲止的代碼
我試圖構建構建一個Lambda和比較日期的功能。到目前爲止,如果原始查詢是A.Include(x => x.B).Include(x => x.B.Select(y => y.C)
,我可以構造字符串"A.B.Bc"
,所以我知道A,B和Bc的類型以及它們相關的方式。
private static IQueryable<T> FilterChangeTrackerToDate<T>(this IQueryable<T> query, string includeString, DateTime targetDateTime)
{
var param = Expression.Parameter(typeof(T), "x");
var prop = Expression.Property(param, includeString + ".CreatedUtc");
var dateConst = Expression.Constant(targetDateTime);
var compare = Expression.LessThanOrEqual(prop, dateConst);
var lambda = Expression.Lambda<Func<T, bool>>(compare, param);
return query.Where(lambda);
}
的問題是,上面的代碼崩潰,因爲"A.B.Bc.CreatedUtc"
是不加載日期屬性的正確方法 - 我需要通過.Select
語句來遍歷此。
的問題
爲了既負載記錄和濾波器它們,我需要動態地建立一個.Select
拉出我所需要的值(其幸運的是,是靜態的基於繼承)並將這些值置於匿名類型中,然後可以使用.Where()
進行過濾。所有這些都需要用最少的泛型來完成,因爲我沒有編譯時類型來驗證,我不得不濫用反射來讓它們工作。
從本質上講,我需要創造這樣的:
.Select(x => new
{
Bc = x.B.Select(z => z.Bc.Select(y => y.CreatedUtc).Where(q => q > DateTime.UtcNow)),
A= x
})
動態,使用字符串 「A.B.Bc」,對於任何級別的嵌套。
資源
這是我看到如何篩選的EF包括方法: LINQ To Entities Include + Where Method
有關動態創建一個選擇這篇文章的會談,但它僅選擇頂層的價值觀和似乎並不喜歡的話可以建立需要我的問題零件的其餘部分:How to create LINQ Expression Tree to select an anonymous type
動態的LINQ
使用System.Linq的。動態庫,我曾經試圖訪問的CreatedUtc
值關BC的:
query = (IQueryable<T>) query.Select(includeString + ".CreatedUtc");
凡includeString = "B.Bc"
,但是這給了我一個例外:
Exception thrown: 'System.Linq.Dynamic.ParseException' in System.Linq.Dynamic.dll
Additional information: No property or field 'Bc' exists in type 'List`1'
當我包括字符串'「B.Bc.CreatedUtc」',我得到這個錯誤:'其它信息:沒有屬性或字段「BC」的類型存在「List'1''。它看起來不像是正確地探索嵌套圖形? – Max
你能在這裏展示更多你的代碼嗎? –
我更新了我的主帖。 – Max