Пример #1
0
        private static Func <T1, T1, bool> CreateMatchExpression <T1>(List <LambdaExpression> expressions)
        {
            Expression buildExpr = null;
            var        param1    = Expression.Parameter(typeof(T1), "p1");
            var        param2    = Expression.Parameter(typeof(T1), "p2");

            for (int i = 0; i < expressions.Count; i++)
            {
                var left  = ParameterReplacer.Replace(expressions[i], expressions[i].Parameters.First(), param1) as LambdaExpression;
                var right = ParameterReplacer.Replace(expressions[i], expressions[i].Parameters.First(), param2) as LambdaExpression;

                var expr = Expression.Equal(left.Body, right.Body);
                if (buildExpr == null)
                {
                    buildExpr = expr;
                }
                else
                {
                    buildExpr = Expression.AndAlso(buildExpr, expr);
                }
            }

            var lambda = Expression.Lambda <Func <T1, T1, bool> >(buildExpr, param1, param2);
            var func   = lambda.Compile();

            return(func);
        }
        public static Expression <Func <TTarget, TResult> > ConvertGenericTypeArgument <TSource, TTarget, TResult>(
            this Expression <Func <TSource, TResult> > root)
        {
            var visitor = new ParameterReplacer(typeof(TSource), typeof(TTarget));

            return(visitor.Visit(root) as Expression <Func <TTarget, TResult> >);
        }
        private static Func <T1, T2, bool> CreateMatchExpression <T1, T2>(ParameterExpression oldParam, List <Expression> leftExpressions, List <Expression> rightExpressions)
        {
            Expression buildExpr = null;
            var        param1    = Expression.Parameter(typeof(T1), "p1");
            var        param2    = Expression.Parameter(typeof(T2), "p2");

            for (int i = 0; i < leftExpressions.Count; i++)
            {
                var left  = ParameterReplacer.Replace(leftExpressions[i], oldParam, param1);
                var right = ParameterReplacer.Replace(rightExpressions[i], oldParam, param2);

                var expr = Expression.Equal(left, right);
                if (buildExpr == null)
                {
                    buildExpr = expr;
                }
                else
                {
                    buildExpr = Expression.AndAlso(buildExpr, expr);
                }
            }

            var lambda = Expression.Lambda <Func <T1, T2, bool> >(buildExpr, param1, param2);
            var func   = lambda.Compile();

            return(func);
        }
Пример #4
0
        public static Expression ReplaceFirstParam(this LambdaExpression expression, Expression newParameter)
        {
            var parameterToRemove = expression.Parameters.ElementAt(0);
            var replacer          = new ParameterReplacer(parameterToRemove, newParameter);

            return(replacer.Visit(expression.Body));
        }
        public LambdaExpression GetExpression(Dictionary <string, object> enviromens = null)
        {
            var enityType = Type.GetType(EntityType);
            List <LambdaExpression> lambdaExpressions = new List <LambdaExpression>();

            foreach (var item in NestedRules)
            {
                lambdaExpressions.Add(item.GetExpression(enviromens));
            }

            foreach (var item in Rules)
            {
                lambdaExpressions.Add(item.GetExpression(enviromens));
            }

            Expression expression = null;

            foreach (var item in lambdaExpressions)
            {
                if (expression == null)
                {
                    expression = item.Body;
                    continue;
                }

                expression = ConditionType == Query.Condition.OrElse ? Expression.OrElse(expression, item.Body) : Expression.AndAlso(expression, item.Body);
            }
            var parameter = Expression.Parameter(enityType, QueryCollection.ParameterSymbol);

            expression = new ParameterReplacer(parameter).Replace(expression);
            return(Expression.Lambda(expression, parameter));
        }
Пример #6
0
        /// <summary>
        /// コンストラクタ、親ノードと結合種類、テーブル、結合式を指定して初期化する
        /// </summary>
        /// <param name="parent">親ノード</param>
        /// <param name="joinType">結合種類</param>
        /// <param name="table">結合するテーブル</param>
        /// <param name="on">結合式</param>
        public Join(IQueryNode parent, JoinType joinType, ITable <TColumns> table, Expression <Func <TColumns, bool> > on)
        {
            var select = table as ISelect <TColumns>;

            if (select is null)
            {
                table = table.AliasedClone();
            }
            else
            {
                QueryNodeHelper.SwitchParent(select, this);
            }

            this.Parent   = parent;
            this.JoinType = joinType;
            this.Table    = table;
            this.Columns  = table.Columns;

            this.Owner.RegisterTable(table);

            this.On = new ElementCode(
                ParameterReplacer.Replace(
                    on.Body,
                    new Dictionary <Expression, object> {
                { on.Parameters[0], table.Columns }
            }
                    ),
                this.Owner.AllColumns
                );
        }
    public static Expression <Func <T1, TResult> > FixParam <T1, T2, TResult>(this Expression <Func <T1, T2, TResult> > expression, T2 parameterValue)
    {
        var parameterToRemove = expression.Parameters.ElementAt(1);
        var replacer          = new ParameterReplacer(parameterToRemove, Expression.Constant(parameterValue, typeof(T2)));

        return(Expression.Lambda <Func <T1, TResult> >(replacer.Visit(expression.Body), expression.Parameters.Where(p => p != parameterToRemove)));
    }
Пример #8
0
    static void Main()
    {
        IQueryable <string> strings = (new[] { "Jon", "Tom", "Holly",
                                               "Robin", "William" }).AsQueryable();


        Expression <Func <string, bool> > firstPredicate  = p => p.Contains("ll");
        Expression <Func <string, bool> > secondPredicate = p => p.Length == 3;
        Expression combined = Expression.OrElse(firstPredicate.Body,
                                                secondPredicate.Body);

        ParameterExpression param    = Expression.Parameter(typeof(string), "p");
        ParameterReplacer   replacer = new ParameterReplacer(param);

        combined = replacer.Visit(combined);

        var lambda = Expression.Lambda <Func <string, bool> >(combined, param);

        var query = strings.Where(lambda);

        foreach (string x in query)
        {
            Console.WriteLine(x);
        }
    }
        public static Expression <Func <T, bool> > Combine <T>(Expression <Func <T, bool> > left, Expression <Func <T, bool> > right)
        {
            var parameter = Expression.Parameter(typeof(T), "p");
            var combined  = new ParameterReplacer(parameter).Visit(Expression.OrElse(left.Body, right.Body));

            return(Expression.Lambda <Func <T, bool> >(combined, parameter));
        }
Пример #10
0
        /// <summary>
        /// Creates a new instance of the <see cref="SelectFilter{T, S}"/> class,
        /// that transposes the item type for the given filter and returns what it evaluates to.
        /// </summary>
        /// <param name="transpose">The function that transposes from T to S.</param>
        /// <param name="filter">The filter to evaluate.</param>
        public SelectFilter(Expression <Func <T, S> > transpose, Filter <S> filter)
        {
            var parameterReplacer = new ParameterReplacer(transpose.Parameters.Single(), Parameter);
            var compiledFilter    = filter.GetCompiledFilter();

            FilterExpression = compiledFilter.GetInvocation(parameterReplacer.Visit(transpose));
        }
    public static Expression <Func <TTo, bool> > CastParameter <TFrom, TTo>(
        this Expression <Func <TFrom, bool> > predicate)
    {
        var parameter = Expression.Parameter(typeof(TTo));
        var body      = new ParameterReplacer(parameter).Visit(predicate.Body);

        return(Expression.Lambda <Func <TTo, bool> >(body, parameter));
    }
        public static LambdaExpression ConvertGenericTypeArgument <TSource, TResult>(
            this Expression <Func <TSource, TResult> > root, Type targetType)
        {
            var visitor    = new ParameterReplacer(typeof(TSource), targetType);
            var expression = visitor.Visit(root);

            return(expression as LambdaExpression);
        }
Пример #13
0
        public From <TColumns> Where(Expression <Func <TColumns, bool> > expression)
        {
            var body = ParameterReplacer.Replace(expression.Body, new Dictionary <Expression, object> {
                { expression.Parameters[0], this.Columns }
            });

            return(this.Where(new Where(this, body)));
        }
Пример #14
0
        public SelectFrom <TSelectedColumns> Select <TSelectedColumns>(Expression <Func <TColumns, TSelectedColumns> > columnsExpression)
        {
            var expr = ParameterReplacer.Replace(columnsExpression.Body, new Dictionary <Expression, object> {
                { columnsExpression.Parameters[0], this.Columns }
            });

            return(new SelectFrom <TSelectedColumns>(this, expr));
        }
Пример #15
0
        /// <summary>
        /// 组合表达式
        /// </summary>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <param name="compose"></param>
        /// <returns></returns>
        public static LambdaExpression Compose(this LambdaExpression first, LambdaExpression second, Func <Expression, Expression, Expression> compose)
        {
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

            var secondBody = ParameterReplacer.ReplaceParameters(map, second.Body);

            return(Expression.Lambda(compose(first.Body, secondBody), first.Parameters));
        }
        public static Expression <Func <T, bool> > ToLambda <T>(this BinaryExpression binaryExpression)
        {
            var parameterExpression = Expression.Parameter(typeof(T));

            var expression = new ParameterReplacer(parameterExpression).Visit(binaryExpression);

            return(Expression.Lambda <Func <T, bool> >(expression, parameterExpression));
        }
Пример #17
0
        /// <summary>
        /// コンストラクタ、親ノード、挿入先テーブルと列の並びを指定して初期化する
        /// </summary>
        /// <param name="parent">親ノード</param>
        /// <param name="table">挿入先テーブル</param>
        /// <param name="columnsExpression">列と設定値を指定する t => new[] { t.A == a, t.B == b } の様な式</param>
        public InsertInto(IQueryNode parent, TableDef <TColumns> table, Expression <Func <TColumns, bool[]> > columnsExpression)
        {
            this.Parent = parent;

            // new [] { bool, bool... } の様な形式以外はエラーとする
            var body = columnsExpression.Body;

            if (body.NodeType != ExpressionType.NewArrayInit)
            {
                throw new ApplicationException();
            }

            // 登録
            var owner = this.Owner;

            owner.RegisterTable(table);

            // bool[] の各要素初期化式を取得する
            var newexpr     = body as NewArrayExpression;
            var expressions = newexpr.Expressions;
            var map         = new Dictionary <Expression, object> {
                { columnsExpression.Parameters[0], table.Columns }
            };
            var availableColumns = owner.AllColumns;
            var tableColumnMap   = table.ColumnMap;
            var columnsOrder     = new ColumnMap();
            var values           = new ElementCode[expressions.Count];

            for (int i = 0; i < values.Length; i++)
            {
                // t.A == a の様に Equal を代入として扱いたいのでそれ以外はエラーとする
                var expression = expressions[i];
                if (expression.NodeType != ExpressionType.Equal)
                {
                    throw new ApplicationException();
                }

                var binary = expression as BinaryExpression;

                // 左辺は代入先の列でなければならない
                var left   = new ElementCode(ParameterReplacer.Replace(binary.Left, map), tableColumnMap);
                var column = left.FindColumns().FirstOrDefault();
                if (column == null)
                {
                    throw new ApplicationException();
                }

                // 右辺は式
                values[i] = new ElementCode(ParameterReplacer.Replace(binary.Right, map), availableColumns);

                // 列の生成元を右辺の式にして列を登録
                columnsOrder.Add(column);
            }

            this.Table     = table;
            this.ColumnMap = columnsOrder;
            this.ValueNode = new ValueSetter(this, columnsOrder, values);
        }
Пример #18
0
        /// <summary>
        /// WHERE句の式を登録する
        /// </summary>
        /// <param name="expression">式</param>
        /// <returns>自分</returns>
        public From <TColumns> Where(Expression <Func <TColumns, bool> > expression)
        {
            var body = ParameterReplacer.Replace(expression.Body, new Dictionary <Expression, object> {
                { expression.Parameters[0], this.Columns }
            });

            this.WhereNode = new Where(this, new ElementCode(body, this.Owner.AllColumns));
            return(this);
        }
Пример #19
0
        private static Expression <Func <A, C> > Compose <A, B, C>(Expression <Func <B, C> > f, Expression <Func <A, A, B> > g, ParameterExpression param)
        {
            var ex = ReplaceExpressions(f.Body, f.Parameters[0], g.Body);

            ex = new ParameterReplacer(param)
                 .Visit(ex);

            return(Expression.Lambda <Func <A, C> >(ex, param));
        }
Пример #20
0
        private static void AddFieldWithIdArgumentIfExists <TContextType>(MappedSchemaProvider <TContextType> schema, Type contextType, Field fieldProp)
        {
            if (!fieldProp.Resolve.Type.IsEnumerableOrArray())
            {
                return;
            }
            var schemaType = schema.Type(fieldProp.ReturnTypeClrSingle);
            // Find the first field named "id" or "<fieldProp.Name>Id" to turn into a field with arguments
            var idFieldDef = schemaType.GetFields().FirstOrDefault(f => f.Name.ToLower() == "id" || f.Name.ToLower() == $"{fieldProp.Name.ToLower()}id");

            if (idFieldDef == null)
            {
                return;
            }

            // Save a little bit of typing and clean things up.
            var idFieldName = idFieldDef.Name;

            // We need to build an anonymous type with id = RequiredField<idFieldDef.Resolve.Type>()
            // Resulting lambda is (a, p) => a.Where(b => b.Id == p.Id).First()
            // This allows us to "insert" .Select() (and .Include()) before the .First()
            var requiredFieldType = typeof(RequiredField <>).MakeGenericType(idFieldDef.Resolve.Type);
            var fieldNameAndType  = new Dictionary <string, Type> {
                { idFieldName, requiredFieldType }
            };
            var  argTypes          = LinqRuntimeTypeBuilder.GetDynamicType(fieldNameAndType);
            var  argTypesValue     = argTypes.GetTypeInfo().GetConstructors()[0].Invoke(new Type[0]);
            var  argTypeParam      = Expression.Parameter(argTypes);
            Type arrayContextType  = schema.Type(fieldProp.ReturnTypeClrSingle).ContextType;
            var  arrayContextParam = Expression.Parameter(arrayContextType);

            var        ctxId = Expression.PropertyOrField(arrayContextParam, $"{char.ToUpper(idFieldName[0])}{idFieldName.Substring(1)}");
            Expression argId = Expression.PropertyOrField(argTypeParam, idFieldName);

            argId = Expression.Property(argId, "Value"); // call RequiredField<>.Value to get the real type without a convert
            var        idBody   = Expression.MakeBinary(ExpressionType.Equal, ctxId, argId);
            var        idLambda = Expression.Lambda(idBody, new[] { arrayContextParam });
            Expression body     = ExpressionUtil.MakeExpressionCall(new[] { typeof(Queryable), typeof(Enumerable) }, "Where", new Type[] { arrayContextType }, fieldProp.Resolve, idLambda);

            body = ExpressionUtil.MakeExpressionCall(new[] { typeof(Queryable), typeof(Enumerable) }, "FirstOrDefault", new Type[] { arrayContextType }, body);
            var contextParam = Expression.Parameter(contextType);
            var lambdaParams = new[] { contextParam, argTypeParam };

            body = new ParameterReplacer().ReplaceByType(body, contextType, contextParam);
            var selectionExpression = Expression.Lambda(body, lambdaParams);
            var name = fieldProp.Name.Singularize();

            if (name == null)
            {
                // If we can't singularize it just use the name plus something as GraphQL doesn't support field overloads
                name = $"{fieldProp.Name}";
            }
            var field = new Field(name, selectionExpression, $"Return a {fieldProp.ReturnTypeClrSingle} by its Id", fieldProp.ReturnTypeClrSingle, argTypesValue);

            schema.AddField(field);
        }
Пример #21
0
        public void ParameterReplacerTest()
        {
            Expression <Func <int, int> > exp1 = (a) => 1 + a;
            var exp2 = ParameterReplacer.Replace <Func <int, int>, Expression <Func <int, int> > >(exp1, new Dictionary <string, object>()
            {
                { "a", 5 }
            });

            exp2.Compile();
        }
Пример #22
0
        public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > one, Expression <Func <T, bool> > another)
        {
            var candidateExpr     = Expression.Parameter(typeof(T), "candidate");
            var parameterReplacer = new ParameterReplacer(candidateExpr);
            var left  = parameterReplacer.Replace(one.Body);
            var right = parameterReplacer.Replace(another.Body);
            var body  = Expression.And(left, right);

            return(Expression.Lambda <Func <T, bool> >(body, candidateExpr));
        }
Пример #23
0
        public static Expression <Func <TDestination, TValue> > ReplaceParameter <TSource, TDestination, TValue>
            (this Expression <Func <TSource, TValue> > expression, Expression <Func <TDestination, TSource> > toExtendWith)
        {
            var replacer = new ParameterReplacer(expression.Parameters.First(), toExtendWith.Body);
            var newBody  = replacer.Visit(expression.Body);

            var newLambda = Expression.Lambda(newBody, toExtendWith.Parameters.First());

            return((Expression <Func <TDestination, TValue> >)newLambda);
        }
Пример #24
0
        public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > exp_left, Expression <Func <T, bool> > exp_right)
        {
            var candidateExpr     = Expression.Parameter(typeof(T), "candidate");
            var parameterReplacer = new ParameterReplacer(candidateExpr);

            var left  = parameterReplacer.Replace(exp_left.Body);
            var right = parameterReplacer.Replace(exp_right.Body);
            var body  = Expression.Or(left, right);

            return(Expression.Lambda <Func <T, bool> >(body, candidateExpr));
        }
        public override Expression <Func <T, bool> > ToExpression()
        {
            var specExpression = _spec.ToExpression();

            var paramExpr = Expression.Parameter(typeof(T));
            var exprBody  = Expression.Not(specExpression.Body);

            var visitedExpr = new ParameterReplacer(paramExpr).Visit(exprBody);
            var finalExpr   = Expression.Lambda <Func <T, bool> >(visitedExpr, paramExpr);

            return(finalExpr);
        }
Пример #26
0
        /// <summary>
        /// 连接表达式或运算
        /// </summary>
        /// <typeparam name="T">参数</typeparam>
        /// <param name="one">原表达式</param>
        /// <param name="another">新表达式</param>
        /// <returns></returns>
        public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > one, Expression <Func <T, bool> > another)
        {
            //创建新参数
            var newParameter = Expression.Parameter(typeof(T), "parameter");

            var parameterReplacer = new ParameterReplacer(newParameter);
            var left  = parameterReplacer.Replace(one.Body);
            var right = parameterReplacer.Replace(another.Body);
            var body  = Expression.Or(left, right);

            return(Expression.Lambda <Func <T, bool> >(body, newParameter));
        }
Пример #27
0
        /// <summary>
        /// Creates and returns an implication expression P ⇒ Q.
        /// As per the definition of implication, <code>Implies(model => model.P, model => model.Q)</code> is exactly equivalent to (though hopefully easier to read than)
        /// <code>
        /// model => !model.P || model.Q
        /// </code>
        /// </summary>
        /// <param name="p">The antecedent expression.</param>
        /// <param name="q">The consequent expression.</param>
        /// <returns>An implication expression.</returns>
        public static Expression <Predicate <TModel> > Implies(Expression <Predicate <TModel> > p, Expression <Predicate <TModel> > q)
        {
            // We essentially want !p.Body || q.Body, but with the parameter expressions in each replaced with a new singular one.
            // That's what ParameterReplacer does for us. Note that the name of the parameter from the first is used. Should we
            // complain if the name of the parameter in the second is different? Seems overkill..
            var pr = new ParameterReplacer(p.Parameters[0].Name);

            return(Expression.Lambda <Predicate <TModel> >(
                       Expression.OrElse(
                           Expression.IsFalse(pr.VisitLambdaBody(p)),
                           pr.VisitLambdaBody(q)),
                       pr.NewParameter));
        }
    private static Expression <Func <T, bool> > Wrap <T>(Expression <Func <T, string> > accessor)
    {
        var stringContains = typeof(String).GetMethod("Contains", new[] { typeof(String) });
        var pe             = Expression.Parameter(typeof(T), "__x4326");
        var newBody        = new ParameterReplacer(pe).Visit(accessor.Body);
        var call           = Expression.Call(
            newBody,
            stringContains,
            Expression.Constant("foo")
            );

        return(Expression.Lambda <Func <T, bool> >(call, pe));
    }
        public void GetTypeToUseTest()
        {
            Expression <Func <Person, int> >    p1 = p => p.Id;
            Expression <Func <Person, int> >    p2 = p => 23;
            Expression <Func <Person, string> > p3 = p => "fdhtfghty";

            p2 = ParameterReplacer.Replace(p2, p2.Parameters[0], p1.Parameters[0]) as Expression <Func <Person, int> >;
            p3 = ParameterReplacer.Replace(p3, p3.Parameters[0], p1.Parameters[0]) as Expression <Func <Person, string> >;

            //var func = RelationshipComparer<Person, Person>.CreateHashCodeOld<Person>(new List<Expression> { p1, p2, p3 }, p1.Parameters[0]);

            // var func = KeyComparer<Person>.CreateGetHashCodeFunc<Person>(new List<LambdaExpression> { p1, p2, p3 });
        }
Пример #30
0
        public static Expression <Func <T, Boolean> > Simplify <T>(this Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }

            var parameters = Expression.Parameter(typeof(T));
            var body = new ParameterReplacer(parameters).Visit(expression) ?? expression;
            var simplified = body is Expression <Func <T, Boolean> > lambda ? lambda : Expression.Lambda <Func <T, Boolean> >(body, parameters);

            return(simplified);
        }
			public static Expression ReplaceParameter(Expression exp, ParameterExpression replace, ParameterExpression withThis)
			{
				var pr = new ParameterReplacer(replace, withThis);
				return pr.Visit(exp);
			}