2013-07-25 4 views
5

MVC4では、ユーザーにSearchボックスを提供して、Tableの値を検索します。 は、だから私はC#で、サーバー側で式を使用したLINQフィルタの実装

を一般的なフィルタ条件を実装しています単一の式に例

表の列

については

Expression<Func<T, bool>> 

を形成するために、複数の式を結合するために助けが必要

MenuText、Role Name(Role.Name mapping)、Actio nName

今すぐ表示する列のいずれかの行にあるABCの検索ボックスにユーザーを入力すると、フィルタリングする必要があります。

モデル

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

私はあなたが

全ブログを使用することができるはず、いくつかの検索IQueryable拡張メソッドを作成している

/// <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

あなたは過去24時間以内にほぼ同じ質問を3回しました... – leppie

答えて

0

ありがとう:プロパティで複数または検索用語を可能

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

検索拡張メソッド:検索は、複数のプロパティをaccrosことができます

検索拡張メソッドNinjaNyeに、私は問題を解決したBuildOrExpressionを借りました

ここに解決策があります

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

これまでのところ私は実装しています投稿はこちらです:

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

GitHubのプロジェクトはここにある(ありOR検索のための余分な拡張子のカップル:

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

あなたはまた、便利ngの記事:

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

関連する問題