protected Expression[] GetNewBodies(ParameterExpression parameter) { var expr1 = Components[0].TargetExpression; var expr2 = Components[1].TargetExpression; var leftVisitor = new ReplaceExpressionVisitor(parameter, expr1.Parameters[0]); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(parameter, expr2.Parameters[0]); var right = rightVisitor.Visit(expr2.Body); return(new[] { left, right }); }
public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( Expression.OrElse(left, right), parameter)); }
private static void GetVisitorExpressions <T>(Expression <Func <T, bool> > firstExpression, Expression <Func <T, bool> > secondExpression, out ParameterExpression parameter, out Expression left, out Expression right) { parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(firstExpression.Parameters[0], parameter); left = leftVisitor.Visit(firstExpression.Body); var rightVisitor = new ReplaceExpressionVisitor(secondExpression.Parameters[0], parameter); right = rightVisitor.Visit(secondExpression.Body); }
/// <summary> /// 合并表达式 /// </summary> /// <typeparam name="T">实体类型</typeparam> /// <param name="expression1">表达式1</param> /// <param name="expression2">表达式2</param> /// <returns></returns> protected virtual Expression <Func <T, bool> > CombineExpression <T>(Expression <Func <T, bool> > expression1, Expression <Func <T, bool> > expression2) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expression1.Parameters[0], parameter); var left = leftVisitor.Visit(expression1.Body); var rightVisitor = new ReplaceExpressionVisitor(expression2.Parameters[0], parameter); var right = rightVisitor.Visit(expression2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left, right), parameter)); }
/// <summary> /// 合并表达式以及参数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <param name="func"></param> /// <returns></returns> private static Expression <Func <T, bool> > AndAlso <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, Func <Expression, Expression, BinaryExpression> func) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( func(left, right), parameter)); }
public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(Guard.NotNull(left), Guard.NotNull(right)), parameter)); }
public static Expression <Func <T, bool> > AndAlso <T>(this Expression <Func <T, bool> > exprLeft, Expression <Func <T, bool> > exprRight) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(exprLeft.Parameters[0], parameter); var newExprLeft = leftVisitor.Visit(exprLeft.Body); var rightVisitor = new ReplaceExpressionVisitor(exprRight.Parameters[0], parameter); var newExprRight = rightVisitor.Visit(exprRight.Body); return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(newExprLeft, newExprRight), parameter)); }
public Expression <Func <TSource, TTarget> > Create(Expression <Func <TSource, TTarget> > translation) { var parameter = translation.Parameters.First(); Dictionary <string, Expression> members = new Dictionary <string, Expression>(); foreach (var item in _baseTypeMappings) { item.GetProperties().Where(p => p.CanRead && p.GetSetMethod() != null) .ToList() .ForEach(p => members[p.Name] = Expression.Property(parameter, p)); } foreach (var mapping in _baseMappings) { var lambda = mapping.ConversionExpression as LambdaExpression; if (lambda != null) { var init = lambda.Body as MemberInitExpression; var visitor = new ReplaceExpressionVisitor(lambda.Parameters.First(), translation.Parameters.First()); if (init != null) { foreach (var item in init.Bindings.OfType <MemberAssignment>()) { members[item.Member.Name] = visitor.Visit(item.Expression); } } } } var memberInit = translation.Body as MemberInitExpression; var newExpression = memberInit != null ? memberInit.NewExpression : translation.Body as NewExpression; if (memberInit == null && newExpression == null) { throw new ArgumentOutOfRangeException("translation", "Only New and MemberInit Expressions are allowed"); } if (memberInit != null) { memberInit.Bindings.ToList() .OfType <MemberAssignment>() .ToList() .ForEach(p => members[p.Member.Name] = p.Expression); } var targetType = typeof(TTarget); var newInit = Expression.MemberInit(newExpression, members.Select(p => Expression.Bind(targetType.GetProperty(p.Key), p.Value))); return(Expression.Lambda <Func <TSource, TTarget> >(newInit, translation.Parameters)); }
private static Expression <Func <T, bool> > GetExpressionInfo( Expression <Func <T, bool> > funcToAdd, Expression <Func <T, bool> > criteria, Func <Expression, Expression, BinaryExpression> functionToApply ) { ParameterExpression parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(criteria.Parameters[0], parameter); Expression left = leftVisitor.Visit(criteria.Body); var rightVisitor = new ReplaceExpressionVisitor(funcToAdd.Parameters[0], parameter); Expression right = rightVisitor.Visit(funcToAdd.Body); return(Expression.Lambda <Func <T, bool> >(functionToApply(left, right), parameter)); }
public static Expression <Func <T, bool> > Combine <T>(this Expression <Func <T, bool> > expression1, Expression <Func <T, bool> > expression2) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expression1.Parameters[0], parameter); var left = leftVisitor.Visit(expression1.Body); var rightVisitor = new ReplaceExpressionVisitor(expression2.Parameters[0], parameter); var right = rightVisitor.Visit(expression2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left ?? throw new InvalidOperationException(nameof(left)), right ?? throw new InvalidOperationException(nameof(right))), parameter)); }
private static Tuple <Expression, Expression, ParameterExpression> VisitExpressions <T>( Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(new Tuple <Expression, Expression, ParameterExpression>(left !, right !, parameter)); }
public static Expression <Func <TEntity, bool> > AttachFilter <TEntity>(Expression <Func <TEntity, bool> > filter, Expression <Func <TEntity, bool> > filterToAttach) { var argument = Expression.Parameter(typeof(TEntity)); var leftVisitor = new ReplaceExpressionVisitor(argument, filter.Parameters[0]); var left = leftVisitor.Visit(filter.Body); var rightVisitor = new ReplaceExpressionVisitor(argument, filterToAttach.Parameters[0]); var right = rightVisitor.Visit(filterToAttach.Body); var temp = Expression.Lambda <Func <TEntity, bool> >( Expression.AndAlso(left, right), argument); return(temp); }
public static ISpecification <T> Or <T>(this ISpecification <T> left, ISpecification <T> right) { var leftQuery = (Query.Query)left.Query; var rightQuery = (Query.Query)right.Query; var leftQueryItems = GetQueryChain(leftQuery); var rightQueryItems = GetQueryChain(rightQuery); leftQuery = leftQueryItems.Last(); rightQuery = rightQueryItems.SkipWhile(x => x.Parameters.QueryType == QueryType.Empty).First(); if (leftQueryItems.Last().Parameters.QueryType != QueryType.Where) { throw new InvalidOperationException("Left specification must ending with Where expression"); } if (rightQueryItems.SkipWhile(x => x.Parameters.QueryType == QueryType.Empty).Count(x => x.Parameters.QueryType != QueryType.Where) > 0) { throw new InvalidOperationException("Right specification should contains only one Where clause"); } var argumentParameter = Expression.Parameter(typeof(T), "obj"); var contextParameter = Expression.Parameter(typeof(IQueryContext), "context"); var leftExpression = (LambdaExpression)leftQuery.Parameters.Expression; var leftPartExpression = new ReplaceExpressionVisitor <ParameterExpression, ParameterExpression>( new ReplaceItem <ParameterExpression, ParameterExpression>(leftExpression.Parameters.First(x => x.Type == typeof(T)), argumentParameter), new ReplaceItem <ParameterExpression, ParameterExpression>(leftExpression.Parameters.FirstOrDefault(x => x.Type == typeof(IQueryContext)), contextParameter)) .Visit(leftExpression.Body); var rightExpression = (LambdaExpression)rightQuery.Parameters.Expression; var rightPartExpression = new ReplaceExpressionVisitor <ParameterExpression, ParameterExpression>( new ReplaceItem <ParameterExpression, ParameterExpression>(rightExpression.Parameters.First(x => x.Type == typeof(T)), argumentParameter), new ReplaceItem <ParameterExpression, ParameterExpression>(rightExpression.Parameters.FirstOrDefault(x => x.Type == typeof(IQueryContext)), contextParameter)) .Visit(rightExpression.Body); var resultExpressionBody = Expression.OrElse(leftPartExpression, rightPartExpression); var query = new Query.Query( leftQueryItems.Last().Parent, new WhereQueryParameter( typeof(T), typeof(T), Expression.Lambda(resultExpressionBody, argumentParameter, contextParameter), QueryType.Where), leftQuery.EntityType); return(new CustomSpecification <T>(query)); }
public static Expression <Func <T, bool> > AndAlso <T>( this Expression <Func <T, bool> > leftExpression, Expression <Func <T, bool> > rightExpression) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(leftExpression.Parameters[0], parameter); var left = leftVisitor.Visit(leftExpression.Body); var rightVisitor = new ReplaceExpressionVisitor(rightExpression.Parameters[0], parameter); var right = rightVisitor.Visit(rightExpression.Body); return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(left, right), parameter)); }
//Take a collection of expressions (right now this will only process the first two because I'm a plum) //Manually visit and combine both expression predicates together into one logically correct predicate //Use that predicate to return the new, shiny, correct expression to pass to Linq for EF querying. private Expression <Func <TFact, bool> > CombineFilters(List <Expression <Func <TFact, bool> > > filters) { ParameterExpression parameterExpression = Expression.Parameter(typeof(TFact)); var leftExpression = filters[0]; var rightExpression = filters[1]; var leftVisitor = new ReplaceExpressionVisitor(leftExpression.Parameters[0], parameterExpression); var newLeftExpression = leftVisitor.Visit(leftExpression.Body); var rightVisitor = new ReplaceExpressionVisitor(rightExpression.Parameters[0], parameterExpression); var newRightExpression = rightVisitor.Visit(rightExpression.Body); return(Expression.Lambda <Func <TFact, bool> >(Expression.AndAlso(newLeftExpression, newRightExpression), parameterExpression)); }
public static Expression <Func <T, bool> > AndAlso <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { var parameter = System.Linq.Expressions.Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(System.Linq.Expressions.Expression.Lambda <Func <T, bool> >( System.Linq.Expressions.Expression.AndAlso(left, right), parameter)); }
public static Expression <Func <T, bool> > AndIf <T>([NotNull] this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, bool condition) { if (!condition) { return(expr1); } var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(left, right), parameter)); }
/// <summary> /// 合併表達式以及參數 /// </summary> private static Expression <Func <T, bool> > AndAlso <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, Func <Expression, Expression, BinaryExpression> func) { ParameterExpression _exprParameter = Expression.Parameter(typeof(T)); ReplaceExpressionVisitor _revLeft = new ReplaceExpressionVisitor(expr1.Parameters[0], _exprParameter); Expression _exprLeft = _revLeft.Visit(expr1.Body); ReplaceExpressionVisitor _revRight = new ReplaceExpressionVisitor(expr2.Parameters[0], _exprParameter); Expression _exprRight = _revRight.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( func(_exprLeft, _exprRight), _exprParameter)); }
// https://stackoverflow.com/questions/457316/combining-two-expressions-expressionfunct-bool/457328#457328 public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > firstExpr, Expression <Func <T, bool> > expr) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(firstExpr.Parameters[0], parameter); var left = leftVisitor.Visit(firstExpr.Body); var rightVisitor = new ReplaceExpressionVisitor(expr.Parameters[0], parameter); var right = rightVisitor.Visit(expr.Body); if (left is null || right is null) { return(firstExpr); } return(Expression.Lambda <Func <T, bool> >( Expression.OrElse(left, right), parameter)); }
public static Expression <Func <T, bool> > AndAlso <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) where T : class { if (expr1 is null) { return(expr2); } var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left !, right !), parameter)); }
public static Expression<Func<T, bool>> CombineExpression<T>(Expression<Func<T, bool>> expr1,Expression<Func<T, bool>> expr2, BinaryOperatorKind kind, string name = "model") { var parameter = Expression.Parameter(typeof(T), name); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); switch (kind) { case BinaryOperatorKind.Or: return Expression.Lambda<Func<T, bool>>(Expression.Or(left, right), parameter); case BinaryOperatorKind.And: return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(left, right), parameter); case BinaryOperatorKind.Equal: break; case BinaryOperatorKind.NotEqual: break; case BinaryOperatorKind.GreaterThan: break; case BinaryOperatorKind.GreaterThanOrEqual: break; case BinaryOperatorKind.LessThan: break; case BinaryOperatorKind.LessThanOrEqual: break; case BinaryOperatorKind.Add: break; case BinaryOperatorKind.Subtract: break; case BinaryOperatorKind.Multiply: break; case BinaryOperatorKind.Divide: break; case BinaryOperatorKind.Modulo: break; case BinaryOperatorKind.Has: break; default: break; } return null; }
public void create_subgraph() { Action op = () => { for (var i = 1; i < 10; i++) { Expression <Func <int, VertexPredicate <TestNode> > > expr = x => node => node.Id.ToString().StartsWith(x.ToString()); var rev = new ReplaceExpressionVisitor(); rev.Replaces["x"] = i; var replacedExpr = rev.Visit(expr.Body); var resultExpr = (Expression <VertexPredicate <TestNode> >)replacedExpr; var cg = _graph.GetChildGraph(resultExpr); } }; var notcached = MeasureTimeSpan(op); //00:00:00.200 var cached = MeasureTimeSpan(op); //00:00:00.001 }
public static Expression <Func <T, bool> > AndOrCustom <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, bool isAnd = true) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); if (isAnd) { return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left, right), parameter)); } return(Expression.Lambda <Func <T, bool> >(Expression.Or(left, right), parameter)); }
public static Expression <Func <T, bool> > AndAlso <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { if (expr2 == null) { return(null); } var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(left ?? throw new InvalidOperationException(), right ?? throw new InvalidOperationException()), parameter)); }
private static (Expression left, Expression right, ParameterExpression[] parameters) MergeExpressionAndParameters( LambdaExpression left, LambdaExpression right) { var parameters = new ParameterExpression[left.Parameters.Count]; var leftExpression = left.Body; var rightExpression = right.Body; for (var i = 0; i < left.Parameters.Count; i++) { parameters[i] = Expression.Parameter(left.Parameters[i].Type); var leftVisitor = new ReplaceExpressionVisitor(left.Parameters[i], parameters[i]); leftExpression = leftVisitor.Visit(leftExpression); var rightVisitor = new ReplaceExpressionVisitor(right.Parameters[i], parameters[i]); rightExpression = rightVisitor.Visit(rightExpression); } return(leftExpression, rightExpression, parameters); }
public void create_subgraph() { Action op = () => { var tasks = Enumerable.Range(1, 9).ToList().ConvertAll(i => Task.Run(() => { Expression <Func <int, VertexPredicate <TestNode> > > expr = x => node => node.Id.ToString().StartsWith(x.ToString()); var rev = new ReplaceExpressionVisitor(); rev.Replaces["x"] = i; var replacedExpr = rev.Visit(expr.Body); var resultExpr = (Expression <VertexPredicate <TestNode> >)replacedExpr; var cg = _graph.GetChildGraph(resultExpr); })); Task.WaitAll(tasks.ToArray()); }; var notcached = MeasureTimeSpan(op); var cached = MeasureTimeSpan(op); }
public IQueryable <TTarget> Render(IQueryable <TTarget> queryable, TSource source) { ReplaceExpressionVisitor visitor = new ReplaceExpressionVisitor( new Dictionary <Expression, Expression> { { SourceConstant, Constant(source) } } ); var filter = (Expression <Func <TTarget, bool> >)visitor.Visit(FilterExpression); queryable = queryable.Where(filter); foreach (string include in Includes) { queryable.Include(include); } return(queryable); }
public void child_graph_cached_on_predicate_result() { for (var j = 0; j < 2; j++) //run two times { for (var i = 2; i < 10; i++) //8 subtree calls each time { Expression <Func <int, int, VertexPredicate <TestNode> > > expr = (x, y) => node => node.Id > x * y; var visitor = new ReplaceExpressionVisitor(); visitor.Replaces["x"] = i; visitor.Replaces["y"] = i; var replacedExpr = visitor.Visit(expr.Body); var resultExpr = (Expression <VertexPredicate <TestNode> >)replacedExpr; var testCount = _graph.GetChildGraph(resultExpr).Vertices.Count() == _graph.Vertices.Count(n => n.Id > i * i); Assert.That(testCount, "Subgraph contains wrong number of Vertices when selection based on predicate."); } } Assert.That(_graph.Cache.Count == 8, "Caching done wrong based on predicate result"); }
public static Expression <Func <T, bool> > AndAlso <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { if (expr1 == null) { throw new ArgumentNullException(nameof(expr1)); } if (expr2 == null) { throw new ArgumentNullException(nameof(expr2)); } var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left, right), parameter)); }
public static Expression ReplaceTargetWith(this Expression self, Expression target, Expression with) { if (self == null) { throw new ArgumentNullException(nameof(self)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (with == null) { throw new ArgumentNullException(nameof(with)); } var visitor = new ReplaceExpressionVisitor(target, with); return(visitor.Visit(self)); }