2016-09-23 3 views
1

既に作成済みの式を変更するにはどうすればよいですか?私は種類のクラス次いる

public class Entity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

私は(私はそれは問題ではありませんと思いますが、質問の開裂性のためにここに追加)グリッドを剣道するデータソースとしてIEnumerable<Entity>>を渡しています。

私は、サーバー側のフィルタリングを実装すると、ページ上の別のinput[text]フィールドを実装している、と次のようにクライアント側でフィルタを追加:

サーバー側で
var grid = $(e).data('kendoGrid'); 
var columns = grid.columns; 
var columnTypes = grid.dataSource.options.schema.model.fields; 
for (var i = 0; i < columns.length; i++) { 
    if (columns[i].field) { 
     var columnDataType = columnTypes[columns[i].field].type; 
     if (columnDataType == 'number' && !isNaN(Number(value))) { 
      var filter = { field: columns[i].field, operator: "eq", value: Number(value) }; 
     } else if (columnDataType == 'string') { 
      var filter = { field: columns[i].field, operator: "contains", value: value }; 
     } 

     gridListFilter.filters.push(filter); 
    } 
} 

var gridDataSource = grid.dataSource; 
console.log(gridListFilter); 
gridDataSource.filter(gridListFilter); 

私が実装しています仮想化ハンドラメソッドにフィルタリングするためのアルゴリズムを以下:

IQueryable<Entity> query = this.GetQuery<Entity>(); 
foreach (var item in dataSourceRequest.Filters) 
{ 
    var paramExpr = Expression.Parameter(typeof(TReturnType), "item"); 
    var expr = item.CreateFilterExpression(paramExpr); 
    var lambda = Expression.Lambda<Func<TReturnType, bool>>(expr, paramExpr); 
    query = query.Where(lambda); 
} 

dataSourceRequestはtelerikライブラリーからタイプDataSourceRequestのです。 item.CreateFilterExpressionは、以下の表現のBinaryExpressionを生成事項:

item => (IIF((item != null), item.Id, 0) == 6999142) OrElse 
((IIF((item != null), item.Name, null) ?? "").ToLower().Contains("6999142".ToLower())) 

どこに「6999142」私はビューからinput[text]から取得した検索文字列です。そして、私は次のようにこの表現を変更したい:

item => (IIF((item != null), item.Id, 0).ToString().Contains("6999142")) OrElse 
((IIF((item != null), item.Name, null) ?? "").ToLower().Contains("6999142".ToLower())) 

すでに再作成新しいものをせずにExpressionを作成し変更する方法はありますか?

もしそうなら、私は何を始めるべきか分からないので、修正のためのサンプルコードを提供できますか?

var kendoExpressionModifier = new KendoExpressionModifier(); 
expr = kendoExpressionModifier.Modify(expr); 

必要な結果を生成します。私は、次の

internal class KendoExpressionModifier : ExpressionVisitor 
{ 
    public Expression Modify(Expression expression) 
    { 
     return Visit(expression); 
    } 

    protected override Expression VisitConditional(ConditionalExpression node) 
    { 
     //converting result of conditional expression to string 
     return Expression.Call(node.IfTrue, typeof(object).GetMethod("ToString")); 
    } 

    protected override Expression VisitBinary(BinaryExpression node) 
    { 
     //replacing '==' operator with '.Contains' 
     if (node.NodeType == ExpressionType.Equal) 
     { 
      var left = this.Visit(node.Left); 
      var right = this.Visit(node.Right); 

      return Expression.Call(left, typeof(string).GetMethod("Contains"), right); 
     } 
     //replacing expression 'a.ToString() ?? ""' with 'a != null ? a.ToString() : ""' 
     else if (node.NodeType == ExpressionType.Coalesce) 
     { 
      var left = this.Visit(node.Left) as MethodCallExpression; 

      return Expression.Condition(
       Expression.MakeBinary(
        ExpressionType.NotEqual, 
        left.Object, 
        Expression.Constant(null)), 
       left, 
       Expression.Constant(string.Empty)); 
     } 

     return base.VisitBinary(node); 
    } 

    protected override Expression VisitConstant(ConstantExpression node) 
    { 
     //replacing constant numeric value with its string representation 
     if (node.Value.GetType() != typeof(string)) 
     { 
      return Expression.Call(node, typeof(object).GetMethod("ToString")); 
     } 

     return base.VisitConstant(node); 
    } 
} 

そして、この修飾子への呼び出しが実装されているJonSkeetさんのコメント@によると

+0

いいえ、式ツリーは設計上不変です。 –

+0

@ JonSkeet ok、この式ツリーをトラバースしていくつかのノードを新しい式ツリーにコピーし、いくつかのノードを別のものに置き換えるのはどうですか?出来ますか? –

+1

はい。 https://msdn.microsoft.com/en-us/library/mt654266.aspxを参照してください。 –

答えて

2

。だから、それが誰かを助けることを願っています。

関連する問題