2011-01-06 5 views
2

Ich versuche, Ergebnisse aus einer Datenbank mit Entity Framework CTP5 zu filtern. Hier ist meine derzeitige Methode.IQueryable <> dynamische Sortierung/Filterung mit GetValue schlägt fehl

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); 
} 

Allerdings habe ich festgestellt, dass GetValue nicht mit Entity Framework funktioniert. Es tut wenn der Typ if IEnumerable<> aber nicht IQueryable<>

Gibt es eine Alternative, die ich verwenden kann, um den gleichen Effekt zu erzeugen?

+1

Der Unterschied zwischen IEnumerable und IQueryable besteht darin, dass Linq for Objects (IEnumerable) Delegaten als Parameter akzeptiert und Code direkt ausführt, sodass alles, was kompiliert werden kann, möglich ist. EF verwendet IQueryable, und sein Ausdrucksparser hat Grenzen dafür, was er erkennen und analysieren kann. –

Antwort

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); 
} 

Sie würde es so nennen so

Forms = Forms.Like(header, filter); 

Ich habe keine Validierung der übergebenen Parameter. Zum Beispiel müssen Sie validieren, dass die Contains-Methode für den Typ der Eigenschaft existiert, für die Sie validieren. So wird es nicht auf einem int oder ähnlichem funktionieren.

+0

Das sieht vielversprechend aus ... Ich werde es versuchen – MyNameIsJob

Verwandte Themen