Exemplo n.º 1
0
        /// <summary>
        /// 使用集合中的元素根据测试条件进行(并且)连接。
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TVar"></typeparam>
        /// <param name="source"></param>
        /// <param name="collection">包含测试条件中第二个参数的对象集合。</param>
        /// <param name="predicate">用于连接的测试函数。</param>
        /// <returns></returns>
        public static IQueryable <TSource> BatchAnd <TSource, TVar>(this IQueryable <TSource> source, IEnumerable <TVar> collection, Expression <Func <TSource, TVar, bool> > predicate)
        {
            if (source == null || collection == null || predicate == null)
            {
                return(source);
            }

            var        parExp  = Expression.Parameter(source.ElementType, "s");
            Expression joinExp = null;

            foreach (var item in collection)
            {
                var exp = ParameterRewriter.Rewrite(predicate, parExp, item);
                joinExp = joinExp == null ? exp : Expression.And(joinExp, exp);
            }

            if (joinExp == null)
            {
                return(source);
            }

            var lambda     = Expression.Lambda <Func <TSource, bool> >(joinExp, parExp);
            var expression = Expression.Call(typeof(Queryable), nameof(Queryable.Where), new[] { typeof(TSource) }, source.Expression, lambda);

            return(source.Provider.CreateQuery <TSource>(expression));
        }
    public TResult Calculate <TResult>(TEntityType entity)
        where TResult : struct
    {
        TResult    result   = default(TResult);
        var        prop     = Expression.Parameter(typeof(TEntityType), "param");
        var        visitor  = new ParameterRewriter(prop);
        var        leftExp  = visitor.Visit(Left.PropertyExpression.Body);
        var        rightExp = visitor.Visit(Right.PropertyExpression.Body);
        Expression body;

        switch (this.Operand.Type)
        {
        case OperandType.Multiplication:
            body = Expression.Multiply(leftExp, rightExp);
            break;

        case OperandType.Addition:
            body = Expression.Add(leftExp, rightExp);
            break;

        case OperandType.Division:
            body = Expression.Divide(leftExp, rightExp);
            break;

        case OperandType.Sunbtraction:
            body = Expression.Subtract(leftExp, rightExp);
            break;

        default:
            throw new Exception("Unknown operand type");
        }
        var lambda = Expression.Lambda <Func <TEntityType, TResult> >(body, prop);
        // compilation is long operation, so you might need to store this Func as property and don't compile it each time
        var func = lambda.Compile();

        result = func(entity);
        return(result);
    }
Exemplo n.º 3
0
        private Expression BuildExecuteBatch(BatchCommandExpression batch)
        {
            var operation = Parameterize(batch.Operation.Body);

            var result      = _translator.Translate(operation);
            var namedValues = NamedValueGatherer.Gather(operation);

            var table = new DataTable();

            foreach (var nv in namedValues)
            {
                var info = GetPropertyInfoFromExpression(nv.Value);
                if (info != null)
                {
                    table.Columns.Add(nv.Name, info.DataType.Value.FromDbType());
                }
                else
                {
                    table.Columns.Add(nv.Name, DataExpressionRow.CreateType(nv.Value.Type));
                }
            }

            var parameters = namedValues.ToDictionary(s => s.Name, s =>
            {
                var expression = s.Value;
                var info       = GetPropertyInfoFromExpression(expression);
                if (info == null)
                {
                    return(expression);
                }

                if (ConvertManager.GetConverter(expression.Type) != null)
                {
                    var convExp = Expression.Call(null, MethodCache.GetConverter, Expression.Constant(expression.Type));
                    expression  = Expression.Call(convExp, MethodCache.ConvertTo, expression, Expression.Constant((DbType)info.DataType));
                }

                return((object)Expression.Lambda(expression, batch.Operation.Parameters[1]).Compile());
            });

            var entities = (IEnumerable)batch.Input.Value;

            foreach (IEntity entity in entities)
            {
                var row = table.NewRow();
                foreach (var nv in parameters)
                {
                    if (nv.Value is Delegate del)
                    {
                        row[nv.Key] = del.DynamicInvoke(entity) ?? DBNull.Value;
                    }
                    else if (nv.Value is Expression exp)
                    {
                        exp = ParameterRewriter.Rewrite(exp, batch.Operation.Parameters[1], entity);
                        var setter = Expression.Lambda(exp, _executor).Compile();
                        row[nv.Key] = DataExpressionRow.Create(exp.Type, setter);
                    }
                }

                table.Rows.Add(row);
            }

            Expression plan;

            if (_isAsync)
            {
                _cancelToken = Expression.Parameter(typeof(CancellationToken), "token");
                plan         = Expression.Call(_executor, MethodCache.DbUpdateAsync,
                                               Expression.Constant(table),
                                               Expression.Constant((SqlCommand)result.QueryText),
                                               Expression.Constant(null, typeof(SqlCommand)),
                                               Expression.Constant(null, typeof(SqlCommand)),
                                               _cancelToken
                                               );
            }
            else
            {
                plan = Expression.Call(_executor, MethodCache.DbUpdate,
                                       Expression.Constant(table),
                                       Expression.Constant((SqlCommand)result.QueryText),
                                       Expression.Constant(null, typeof(SqlCommand)),
                                       Expression.Constant(null, typeof(SqlCommand))
                                       );
            }

            if (operation.NodeType != (ExpressionType)DbExpressionType.Insert)
            {
                return(plan);
            }

            return(Expression.Call(typeof(ExecutionBuilder),
                                   _isAsync ? nameof(ExecutionBuilder.UpdateEntitiesAsync) : nameof(ExecutionBuilder.UpdateEntities), null,
                                   plan,
                                   Expression.Constant(table, typeof(DataTable)),
                                   Expression.Constant(entities, typeof(IEnumerable))));
        }
Exemplo n.º 4
0
 public override Expression CreateSortKeyExpression(ParameterExpression itemExpression)
 {
     return(ParameterRewriter.Rewrite(this.lambda.Body, this.lambda.Parameters[0], itemExpression));
 }
Exemplo n.º 5
0
 public static LambdaExpression ReplaceParameter(this LambdaExpression expression, Type acceptsType,
                                                 ParameterExpression newParam)
 {
     return(ParameterRewriter.ReplaceParameter(acceptsType, expression, newParam));
 }
    public static Expression <Func <U, R> > RewriteParameter <T, U, R>(this Expression <Func <T, R> > expression)
    {
        var rewriter = new ParameterRewriter <T, U>();

        return((Expression <Func <U, R> >)rewriter.Visit(expression));
    }