2016-07-14 2 views
0

나는 다음과 같은 설정이 있습니다동적으로 표현 트리를 구성

public class ProductSpecification { 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

public class Product { 
    public IEnumerable<ProductSpecification> Specifications { get; set; } 
} 

내가 프로그래밍 C#에서 다음 ExpressionTree 구성하려면 : 지금까지이 작업을 수행하기 위해 관리했습니다

p => p.Specifications.Any(s=>s.Name.Contains("name_val") && s.Value.Contains("value_val")) 

을하지만, 최종 결과에 가깝지도 않습니다.

public ExpressionBuilder AndStartsWith(string property, string value) 
    { 
     var arguments = new Dictionary<object, Type> 
     { 
      { value, typeof(string)}, 
      { StringComparison.InvariantCultureIgnoreCase, typeof(StringComparison)} 
     }; 

     MethodCallExpression methodExpression = GetExpressionMethod(property, "StartsWith", arguments); 
     _accumulator = Expression.AndAlso(_accumulator, methodExpression); 

     return this; 
    } 

private MethodCallExpression GetExpressionMethod(string property, string methodName, Dictionary<object, Type> arguments) { 
     MethodInfo method = typeof(string).GetMethod(methodName, arguments.Values.ToArray()); 
     Expression source = GetExpressionBody(property); 
     IEnumerable<ConstantExpression> argumentsExpressions = arguments.Select(x => Expression.Constant(x.Key, x.Value)); 
     MethodCallExpression methodExpression = Expression.Call(source, method, argumentsExpressions); 

     return methodExpression; 
    } 

나에게 해결책이 있습니까?

답변

1

힌트를 사용하면 컴파일러에서 빌드 할 대상 트리를 볼 수 있습니다.

public Expression<Func<Product, bool>> GenerateProductExpression() 
{ 
    var param = Expression.Parameter(typeof(Product), "p"); 
    var nameValue = Expression.Constant("name_val"); 
    var valueValue = Expression.Constant("name_val"); 
    var specifications = Expression.Property(param, "Specifications"); 
    var body = 
     Expression.Call(typeof(Enumerable), "Any", new[] { typeof(ProductSpecification) }, 
      specifications, GenerateAnyPredicate(nameValue, valueValue) 
     ); 
    return Expression.Lambda<Func<Product, bool>>(body, param); 
} 

public Expression<Func<ProductSpecification, bool>> GenerateAnyPredicate(
     Expression nameValue, Expression valueValue) 
{ 
    var param = Expression.Parameter(typeof(ProductSpecification), "s"); 
    var name = Expression.Property(param, "Name"); 
    var value = Expression.Property(param, "Value"); 
    var body = Expression.AndAlso(
     Expression.Call(name, "Contains", null, nameValue), 
     Expression.Call(value, "Contains", null, valueValue) 
    ); 
    return Expression.Lambda<Func<ProductSpecification, bool>>(body, param); 
} 
+0

우수한 사람 :

Expression<Func<Product, bool>> expr = p => p.Specifications.Any(s=>s.Name.Contains("name_val") && s.Value.Contains("value_val")); 

어쨌든, 여기에 당신이 그 표현을 구축 할 수있는 방법! 고마워. –

관련 문제