2013-07-25 14 views
5

In MVC4 stelle ich dem Benutzer Suchfeld zur Verfügung, um jeden Wert in der Tabelle zu suchen. So auf Server-Seite Generic Filter Zustand Ich bin der Umsetzung in C#LINQ-Filterimplementierung mit Ausdrücken

eine Hilfe benötigen mehrere Ausdrücke zu kombinieren einzelnen Ausdruck

Expression<Func<T, bool>> 

Für Beispiel

Tabellenspalten

zu bilden

MenuText, Rollenname (Role.Name Mapping), Actio nName

Jetzt, wenn Benutzer in Suchfeld für ABC eingegeben, die in einer der Zeilen in Spalten angezeigt werden können, müssen Sie filtern.

Modell

public class Menu 
{ 
    public string MenuText {get;set;} 
    public Role Role {get;set;} 
    public string ActionName {get;set;} 
} 

public class Role 
{ 
    public string Name {get;set;} 
} 

Bisher habe ich umgesetzt

/// <summary> 
    /// string[] properties property.Name (MenuText, ActionName), including deeper Mapping names such as (Role.Name) 
    /// </summary> 
    public static Expression<Func<T, bool>> FilterKey<T>(string filterText, params string[] properties) 
    { 
     ParameterExpression parameter = Expression.Parameter(typeof (T)); 
     Expression[] propertyExpressions = properties.Select(
      x => !string.IsNullOrEmpty(x) ? GetDeepPropertyExpression(parameter, x) : null).ToArray(); 

     Expression<Func<T, bool>> predicate = PredicateBuilder.False<T>(); 
     foreach (Expression expression in propertyExpressions) 
     { 
      var toLower = Expression.Call(expression, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)); 
      var like = Expression.Call(toLower, typeof(string).GetMethod("Contains"), Expression.Constant(filterText.ToLower())); 
      //TODO: Combine expressions to form single Expression<Func<T, bool>> expression 

     } 
     return predicate; 
    } 

     /// <summary> 
     /// To Get Deeper Properties such as Role.Name Expressions 
     /// </summary> 
     private static Expression GetDeepPropertyExpression(Expression initialInstance, string property) 
     { 
      Expression result = null; 
      foreach (string propertyName in property.Split('.')) 
      { 
       Expression instance = result ?? initialInstance; 
       result = Expression.Property(instance, propertyName); 
      } 
      return result; 
     } 
+0

Sie haben fast identische Frage 3 Mal in den letzten 24 Stunden gefragt ... – leppie

Antwort

0

Dank zu NinjaNye, ich habe BuildOrExpression ausgeliehen, die mein Problem gelöst

Hier ist die Lösung

public static Expression<Func<T, bool>> FilterKey<T>(string filterText, params string[] properties) 
     { 
      ParameterExpression parameter = Expression.Parameter(typeof (T)); 
      Expression[] propertyExpressions = properties.Select(
       x => !string.IsNullOrEmpty(x) ? GetDeepPropertyExpression(parameter, x) : null).ToArray(); 

      Expression like= propertyExpressions.Select(expression => Expression.Call(expression, typeof (string).GetMethod("ToLower", Type.EmptyTypes))).Select(toLower => Expression.Call(toLower, typeof (string).GetMethod("Contains"), Expression.Constant(filterText.ToLower()))).Aggregate<MethodCallExpression, Expression>(null, (current, ex) => BuildOrExpression(current, ex)); 
      return Expression.Lambda<Func<T, bool>>(like, parameter); 
     } 

     private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd) 
     { 
      if (existingExpression == null) 
      { 
       return expressionToAdd; 
      } 

      //Build 'OR' expression for each property 
      return Expression.OrElse(existingExpression, expressionToAdd); 
     } 


     private static Expression GetDeepPropertyExpression(Expression initialInstance, string property) 
     { 
      Expression result = null; 
      foreach (string propertyName in property.Split('.')) 
      { 
       Expression instance = result ?? initialInstance; 
       result = Expression.Property(instance, propertyName); 
      } 
      return result; 
     } 
6

ich ein paar Suche IQueryable Erweiterungsmethoden erstellt haben, sollten Sie

Voll Blog verwenden können Beitrag ist hier:

http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable

GitHub Projekt ist hier (hat ein paar zusätzliche Erweiterungen für OR Suche:

string searchTerm = "test"; 
var results = context.Menu.Search(menu => menu.MenuText, searchTerm).ToList(); 

//OR for Role name 
string searchTerm = "test"; 
var results = context.Menu.Search(menu => menu.Role.Name, searchTerm).ToList(); 

:

https://github.com/ninjanye/SearchExtensions

public static class QueryableExtensions 
{ 
    public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, string searchTerm) 
    { 
     if (String.IsNullOrEmpty(searchTerm)) 
     { 
      return source; 
     } 

     // The below represents the following lamda: 
     // source.Where(x => x.[property] != null 
     //    && x.[property].Contains(searchTerm)) 

     //Create expression to represent x.[property] != null 
     var isNotNullExpression = Expression.NotEqual(stringProperty.Body, Expression.Constant(null)); 

     //Create expression to represent x.[property].Contains(searchTerm) 
     var searchTermExpression = Expression.Constant(searchTerm); 
     var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression); 

     //Join not null and contains expressions 
     var notNullAndContainsExpression = Expression.AndAlso(isNotNullExpression, checkContainsExpression); 

     var methodCallExpression = Expression.Call(typeof(Queryable), 
                "Where", 
                new Type[] { source.ElementType }, 
                source.Expression, 
                Expression.Lambda<Func<T, bool>>(notNullAndContainsExpression, stringProperty.Parameters)); 

     return source.Provider.CreateQuery<T>(methodCallExpression); 
    } 
} 

Das man so etwas schreiben können Sie können auch die folgenden finden ng Beiträge nützlich:

Suche Erweiterung Methode, die Suche accros mehrere Eigenschaften ermöglicht:

http://jnye.co/Posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees

Search-Extension-Methode, die mehr oder Suchbegriffe auf einer Eigenschaft erlaubt:

http://jnye.co/Posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees

Verwandte Themen