2011-01-06 75 views
2

我試圖使用Entity Framework CTP5過濾來自數據庫的結果。這是我目前的方法。IQueryable <>使用GetValue進行動態排序/過濾失敗

IQueryable<Form> Forms = DataContext.CreateFormContext().Forms; 
foreach(string header in Headers) { 
    Forms = Forms.Where(f => f.GetType() 
           .GetProperty(header) 
           .GetValue(f, null) 
           .ToString() 
           .IndexOf(filter, 
            StringComparison.InvariantCultureIgnoreCase) >= 0); 
} 

但是,我發現GetValue不能使用實體框架。它在IEnumerable<>而不是IEnumerable<>而不是IQueryable<>

是否有替代方案可以用來產生相同的效果?

+1

IEnumerable和IQueryable之間的區別在於Linq for Objects(IEnumerable)將委託作爲參數並直接執行代碼,因此編譯的任何內容都是可能的。 EF使用IQueryable,它的表達式解析器對它能夠識別和解析的內容有限制。 – 2011-01-08 07:23:03

回答

3
public static IQueryable<T> Like<T>(this IQueryable<T> source, string propertyName, string keyword) { 
    Type type = typeof(T); 
    ParameterExpression parameter = Expression.Parameter(type, "param"); 
    MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, type.GetProperty(propertyName)); 

    ConstantExpression constant = Expression.Constant("%" + keyword + "%"); 
    MethodInfo contains = memberAccess.Type.GetMethod("Contains"); 

    MethodCallExpression methodExp = Expression.Call(memberAccess, contains, Expression.Constant(keyword)); 
    Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(methodExp, parameter); 
    return source.Where(lambda); 
} 

你叫它像這樣

Forms = Forms.Like(header, filter); 

我沒有做過傳遞的參數的任何驗證。例如,您必須驗證Contains方法是否存在於要驗證的屬性的類型上。所以它不會在int或類似的東西上工作。

+0

這看起來很有希望...我會給它一個鏡頭 – MyNameIsJob 2011-01-06 17:12:47

相關問題