/// <summary> /// Visits the instance function. /// </summary> private static void VisitFunc(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, string func, string suffix, params int[] adjust) { visitor.ResultBuilder.Append(func).Append("("); var isInstanceMethod = expression.Object != null; if (isInstanceMethod) { visitor.Visit(expression.Object); } for (int i = 0; i < expression.Arguments.Count; i++) { var arg = expression.Arguments[i]; if (isInstanceMethod || (i > 0)) { visitor.ResultBuilder.Append(", "); } visitor.Visit(arg); AppendAdjustment(visitor, adjust, i + 1); } visitor.ResultBuilder.Append(suffix).Append(")"); AppendAdjustment(visitor, adjust, 0); }
/// <summary> /// Visits the instance function for Trim specific handling. /// </summary> private static void VisitParameterizedTrimFunc(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, string func) { visitor.ResultBuilder.Append(func).Append("("); visitor.Visit(expression.Object); var arg = expression.Arguments[0]; if (arg != null) { visitor.ResultBuilder.Append(", "); if (arg.NodeType == ExpressionType.Constant) { var constant = (ConstantExpression)arg; if (constant.Value is char) { visitor.AppendParameter((char)constant.Value); } else { var args = constant.Value as IEnumerable <char>; if (args == null) { throw new NotSupportedException("String.Trim function only supports IEnumerable<char>"); } var enumeratedArgs = args.ToArray(); if (enumeratedArgs.Length != 1) { throw new NotSupportedException("String.Trim function only supports a single argument: " + expression); } visitor.AppendParameter(enumeratedArgs[0]); } } else { visitor.Visit(arg); } } visitor.ResultBuilder.Append(")"); }
/// <summary> /// Visits the instance function. /// </summary> private static void VisitFunc(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, string func, string suffix, params int[] adjust) { visitor.ResultBuilder.Append(func).Append("("); var isInstanceMethod = expression.Object != null; if (isInstanceMethod) { visitor.Visit(expression.Object); } for (int i = 0; i < expression.Arguments.Count; i++) { var arg = expression.Arguments[i]; if (isInstanceMethod || (i > 0)) { visitor.ResultBuilder.Append(", "); } if (arg.NodeType == ExpressionType.NewArrayInit) { // Only trim methods use params[], only one param is supported var args = ((NewArrayExpression)arg).Expressions; if (args.Count != 1) { throw new NotSupportedException("Method call only supports a single parameter: " + expression); } visitor.Visit(args[0]); } else { visitor.Visit(arg); } AppendAdjustment(visitor, adjust, i + 1); } visitor.ResultBuilder.Append(suffix).Append(")"); AppendAdjustment(visitor, adjust, 0); }
/// <summary> /// Visits the SQL like expression. /// </summary> private static void VisitSqlLike(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, string likeFormat) { visitor.ResultBuilder.Append("("); visitor.Visit(expression.Object); visitor.ResultBuilder.AppendFormat(" like {0}) ", likeFormat); var arg = expression.Arguments[0] as ConstantExpression; var paramValue = arg != null ? arg.Value : visitor.RegisterEvaluatedParameter(expression.Arguments[0]); visitor.Parameters.Add(paramValue); }
/// <summary> /// Visits member expression argument. /// </summary> private static void VisitArg(CacheQueryExpressionVisitor visitor, MethodCallExpression expression, int idx, bool lower) { if (lower) { visitor.ResultBuilder.Append("lower("); } visitor.Visit(expression.Arguments[idx]); if (lower) { visitor.ResultBuilder.Append(")"); } }
/// <summary> /// Visits string.Compare method /// </summary> private static void VisitStringCompare(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, bool ignoreCase) { // Ex: nvl2(?, casewhen(_T0.NAME = ?, 0, casewhen(_T0.NAME >= ?, 1, -1)), 1) visitor.ResultBuilder.Append("nvl2("); visitor.Visit(expression.Arguments[1]); visitor.ResultBuilder.Append(", casewhen("); VisitArg(visitor, expression, 0, ignoreCase); visitor.ResultBuilder.Append(" = "); VisitArg(visitor, expression, 1, ignoreCase); visitor.ResultBuilder.Append(", 0, casewhen("); VisitArg(visitor, expression, 0, ignoreCase); visitor.ResultBuilder.Append(" >= "); VisitArg(visitor, expression, 1, ignoreCase); visitor.ResultBuilder.Append(", 1, -1)), 1)"); }
/// <summary> /// Visits the property call expression. /// </summary> public static bool VisitPropertyCall(MemberExpression expression, CacheQueryExpressionVisitor visitor) { string funcName; if (!Properties.TryGetValue(expression.Member, out funcName)) { return(false); } visitor.ResultBuilder.Append(funcName).Append('('); visitor.Visit(expression.Expression); visitor.ResultBuilder.Append(')'); return(true); }