public IExpression Convert(TContext context, IStatementBase statement, Operand operand) { if (operand == null) { return(null); } Type type; switch (operand) { case Operand.FieldOperand field: return(this.GetField(context, statement, field.Name)); case Operand.UnaryOperand unary: return(new UnaryExpression( unary.Type.GetOperator(this.GetOperandValueType(context, unary.Operand)), this.Convert(context, statement, unary.Operand) )); case Operand.BinaryOperand binary: type = this.GetOperandValueType(context, binary); return(type == typeof(string) ? (IExpression)MethodExpression.Function("concat", this.Convert(context, statement, binary.Left), this.Convert(context, statement, binary.Right)) : new BinaryExpression( binary.Type.GetOperator(type), this.Convert(context, statement, binary.Left), this.Convert(context, statement, binary.Right))); case Operand.FunctionOperand function: if (function.Arguments == null || function.Arguments.Length == 0) { return(MethodExpression.Function(function.Name)); } else { return(MethodExpression.Function(function.Name, function.Arguments.Select(arg => this.Convert(context, statement, arg)).ToArray())); } case Operand.AggregateOperand aggregate: return(this.GenerateAggregate(context, statement, aggregate)); } type = operand.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Operand.ConstantOperand <>)) { return(this.GetValue(context, statement, operand.GetType().GetMethod("ToObject").Invoke(operand, null))); } throw new DataException($"Unsupported {operand.GetType().FullName} operand type."); }
protected virtual void VisitMethod(ExpressionVisitorContext context, MethodExpression expression) { var methodName = this.Dialect.GetMethodName(expression); //先输出方法或变量名 context.Write(methodName); if (expression.MethodType == MethodType.Function) { context.Write("("); if (expression is AggregateExpression aggregate && aggregate.Distinct) { context.Write("DISTINCT "); } if (expression.Arguments != null) { var index = 0; foreach (var argument in expression.Arguments) { if (index++ > 0) { context.Write(","); } var parenthesized = argument != null && typeof(IStatementBase).IsAssignableFrom(argument.GetType()); if (parenthesized) { context.Write("("); } this.OnVisit(context, argument); if (parenthesized) { context.Write(")"); } } } context.Write(")"); } if (!string.IsNullOrEmpty(expression.Alias)) { context.Write(" AS " + this.GetAlias(expression.Alias)); } }
public string GetMethodName(MethodExpression method) { switch (method) { case AggregateExpression aggregate: return(aggregate.Method.ToString()); case SequenceExpression sequence: return(sequence.Method.ToString()); default: return(method.Name); } }
protected virtual IExpression VisitMethod(MethodExpression expression) { var methodName = this.Dialect.GetMethodName(expression); var isFunction = char.IsLetter(methodName[0]) || methodName[0] == '_'; //先输出方法或变量名 _output.Append(methodName); if (isFunction) { _output.Append("("); if (expression.Arguments != null) { var index = 0; foreach (var argument in expression.Arguments) { if (index++ > 0) { _output.Append(","); } this.Visit(argument); } } _output.Append(")"); } if (!string.IsNullOrEmpty(expression.Alias)) { _output.Append(" AS " + this.GetAlias(expression.Alias)); } return(expression); }