/// <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); }
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)))); }
public override Expression CreateSortKeyExpression(ParameterExpression itemExpression) { return(ParameterRewriter.Rewrite(this.lambda.Body, this.lambda.Parameters[0], itemExpression)); }
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)); }