public bool TryMatch(MemberExpression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { MemberCallDelegate mcd; if (SupportedMembers.TryGetValue(expression.Member, out mcd)) { mcd(expression, queryBuilder, visitExpression, context); return true; } return false; }
private static bool CompareString(bool equal, MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { var count = methodCall.Arguments.Count; if (count != 2 && count != 3) return false; //TODO: handle Oracle incorrect handling of empty string var ce = methodCall.Arguments[0] as ConstantExpression; if (ce != null && ce.Value == null) return GuardForNull(equal, methodCall.Arguments[1], queryBuilder, visitExpression, context); ce = methodCall.Arguments[1] as ConstantExpression; if (ce != null && ce.Value == null) return GuardForNull(equal, methodCall.Arguments[0], queryBuilder, visitExpression, context); if (count == 2) { queryBuilder.Append("("); if (context.InSelect) queryBuilder.Append(" CASE WHEN "); visitExpression(methodCall.Arguments[0]); if (equal) queryBuilder.Append(" = "); else queryBuilder.Append(" <> "); visitExpression(methodCall.Arguments[1]); } else { var cmpValue = methodCall.Arguments[2] as ConstantExpression; if (methodCall.Arguments[2].Type == typeof(bool) && cmpValue != null) { queryBuilder.Append("("); if (context.InSelect) queryBuilder.Append(" CASE WHEN "); EscapeForLike(equal, (bool)cmpValue.Value, methodCall, queryBuilder, visitExpression); } else if (methodCall.Arguments[2].Type == typeof(StringComparison)) { var cmpVal = (StringComparison)cmpValue.Value; var ignoreCase = cmpVal != StringComparison.CurrentCulture && cmpVal != StringComparison.InvariantCulture && cmpVal != StringComparison.Ordinal; queryBuilder.Append("("); if (context.InSelect) queryBuilder.Append(" CASE WHEN "); EscapeForLike(equal, ignoreCase, methodCall, queryBuilder, visitExpression); } else return false; } if (context.InSelect) queryBuilder.Append(" THEN 'Y' ELSE 'N' END"); queryBuilder.Append(")"); return true; }
public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { var mce = expression as MethodCallExpression; if (mce == null || !mce.Method.IsGenericMethod) return false; MethodCallDelegate mcd; if (SupportedMethods.TryGetValue(mce.Method.GetGenericMethodDefinition(), out mcd)) { return mcd(mce, queryBuilder, visitExpression); } return false; }
public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { var mce = expression as MethodCallExpression; if (mce == null) return false; MethodCallDelegate mcd; if (SupportedMethods.TryGetValue(mce.Method, out mcd)) { mcd(mce, queryBuilder, visitExpression, context); return true; } return false; }
public SubqueryParts(QueryParts parentQuery, bool canQueryInMemory, Expression selector, string contextName, QueryContext context) : base(parentQuery.Locator, contextName, parentQuery.ConverterFactory, parentQuery.Parameters, context, parentQuery.Simplifications, parentQuery.ExpressionMatchers, parentQuery.MemberMatchers, parentQuery.ProjectionMatchers) { this.CanQueryInMemory = canQueryInMemory; this.ParentQuery = parentQuery; this.Selector = selector; }
public bool TryMatch(MemberExpression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { Dictionary<Type, MemberCallDelegate> dict; var member = expression.Member; if (member.DeclaringType.IsGenericType && SupportedMembers.TryGetValue(member.Name, out dict)) { MemberCallDelegate mcd; if (dict.TryGetValue(member.DeclaringType.GetGenericTypeDefinition(), out mcd)) { mcd(expression, queryBuilder, visitExpression, context); return true; } } return false; }
public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { var be = expression as BinaryExpression; if (be == null) return false; if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { var ceZero = be.Right as ConstantExpression ?? be.Left as ConstantExpression; var ceMethod = be.Left as MethodCallExpression ?? be.Right as MethodCallExpression; if (ceZero == null || ceMethod == null || !ceZero.Value.Equals(0) || !CompareMethods.Contains(ceMethod.Method)) return false; return CompareString(expression.NodeType == ExpressionType.Equal, ceMethod, queryBuilder, visitExpression, context); } return false; }
//actually this is not correct because ToString uses regional settings, but let's ignore it for now private static void ValueToString(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { queryBuilder.Append("CAST("); visitExpression(methodCall.Object); queryBuilder.Append(" AS VARCHAR(4000))"); }
public SubqueryParts(QueryParts parentQuery, Expression selector, string contextName, QueryContext context) : this(parentQuery, false, selector, contextName, context) { }
private static void GetLength(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { queryBuilder.Append("(SELECT COUNT(*) FROM TABLE("); visitExpression(memberCall.Expression); queryBuilder.Append("))"); }
private static bool GuardForNull(bool equal, Expression exp, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { if (context.InSelect) { queryBuilder.Append(" CASE WHEN "); visitExpression(exp); if (equal) queryBuilder.Append(" IS NULL THEN 'Y' ELSE 'N' END"); else queryBuilder.Append(" IS NULL THEN 'N' ELSE 'Y' END"); } else { visitExpression(exp); if (equal) queryBuilder.Append(" IS NULL"); else queryBuilder.Append(" IS NOT NULL"); } return true; }
public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName, QueryContext context) { var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName, context); visitor.VisitQueryModel(queryModel); return visitor.QueryParts; }
public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, string contextName, QueryContext context) { return ParseSubquery(queryModel, parentQuery, false, contextName, context); }
private SubqueryGeneratorQueryModelVisitor(QueryParts parentQuery, bool canQueryInMemory, Expression selector, string contextName, QueryContext context) { QueryParts = new SubqueryParts(parentQuery, canQueryInMemory, selector, contextName, context); }
private static bool CheckForNull(Expression exp, StringBuilder queryBuilder, QueryContext context) { var ce = exp as ConstantExpression; if (ce == null || ce.Value != null) return false; if (context.InSelect) queryBuilder.Append("'N'"); else queryBuilder.Append(" 0=1"); return true; }
private static void Compare(bool before, bool after, MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { bool ignoreCase = false; ConstantExpression ce; if (methodCall.Arguments.Count == 2) { ce = methodCall.Arguments[1] as ConstantExpression; switch ((StringComparison)ce.Value) { case StringComparison.CurrentCulture: case StringComparison.InvariantCulture: case StringComparison.Ordinal: break; default: ignoreCase = true; break; } } if (context.InSelect) queryBuilder.Append(" CASE WHEN"); else queryBuilder.Append("("); ce = methodCall.Object as ConstantExpression; if (ce != null) { if (ignoreCase) visitExpression(ConstantExpression.Constant((ce.Value as string).ToUpper(), ce.Type)); else visitExpression(ce); } else { if (ignoreCase) { queryBuilder.Append(" UPPER("); visitExpression(methodCall.Object); queryBuilder.Append(")"); } else visitExpression(methodCall.Object); } bool asLike = before || after; if (asLike) queryBuilder.Append(" LIKE "); else queryBuilder.Append(" = "); if (before) queryBuilder.Append("'%' || "); ce = methodCall.Arguments[0] as ConstantExpression; if (ce != null) { if (asLike) { var value = ce.Value as string; if (ignoreCase) value = value.ToUpper(); value = value.Replace(@"\", @"\\").Replace(@"_", @"\_").Replace(@"%", @"\%"); visitExpression(ConstantExpression.Constant(value, ce.Type)); } else if (ignoreCase) visitExpression(ConstantExpression.Constant((ce.Value as string).ToUpper(), ce.Type)); else visitExpression(ce); } else { if (asLike) { if (ignoreCase) queryBuilder.Append(" UPPER("); queryBuilder.Append("REPLACE(REPLACE(REPLACE("); visitExpression(methodCall.Object); queryBuilder.Append(@", '\','\\'), '_','\_'), '%','\%')"); if (ignoreCase) queryBuilder.Append(")"); } else if (ignoreCase) { queryBuilder.Append(" UPPER("); visitExpression(methodCall.Object); queryBuilder.Append(")"); } else visitExpression(methodCall.Object); } if (after) queryBuilder.Append(" || '%'"); if (asLike) queryBuilder.Append(@" ESCAPE '\' "); if (context.InSelect) queryBuilder.Append(" THEN 'Y' ELSE 'N' END"); else queryBuilder.Append(")"); }
/* private static void WithFormat(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, bool inSelect, bool inWhere) { queryBuilder.Append("format("); var index = queryBuilder.Length; visitExpression(methodCall.Arguments[0]); var count = methodCall.Arguments.Count - 1; var substr = queryBuilder.ToString(index, queryBuilder.Length - index); for (int i = 0; i < count; i++) substr = substr.Replace("{" + i + "}", "%" + (i + 1) + "$s"); queryBuilder.Length = index; queryBuilder.Append(substr); for (int i = 0; i < count; i++) { queryBuilder.Append(","); visitExpression(methodCall.Arguments[i + 1]); } queryBuilder.Append(")"); } private static void WithFormatArray(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, bool inSelect, bool inWhere) { queryBuilder.Append("format("); var index = queryBuilder.Length; visitExpression(methodCall.Arguments[0]); var args = (NewArrayExpression)methodCall.Arguments[1]; var count = args.Expressions.Count; var substr = queryBuilder.ToString(index, queryBuilder.Length - index); for (int i = 0; i < count; i++) substr = substr.Replace("{" + i + "}", "%" + (i + 1) + "$s"); queryBuilder.Length = index; queryBuilder.Append(substr); for (int i = 0; i < count; i++) { queryBuilder.Append(","); visitExpression(args.Expressions[i]); } queryBuilder.Append(")"); } */ private static void ReplaceString(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { queryBuilder.Append("REPLACE("); visitExpression(methodCall.Object); queryBuilder.Append(","); visitExpression(methodCall.Arguments[0]); queryBuilder.Append(","); visitExpression(methodCall.Arguments[1]); queryBuilder.Append(")"); }
private static void MatchStringToUpper(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { queryBuilder.Append("UPPER("); visitExpression(methodCall.Object); queryBuilder.Append(")"); }
private static void MatchStringStartsWith(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { if (!CheckForNull(methodCall.Arguments[0], queryBuilder, context)) Compare(false, true, methodCall, queryBuilder, visitExpression, context); }
private static void IsNullOrWhiteSpace(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { //TODO different from C# queryBuilder.Append("TRIM("); visitExpression(methodCall.Arguments[0]); queryBuilder.Append(") IS NULL "); }
private static void IsNullOrEmpty(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { //TODO check if length is greater than 0 visitExpression(methodCall.Arguments[0]); queryBuilder.Append(" IS NULL "); }
private static void GetStringLength(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context) { queryBuilder.Append("length("); visitExpression(memberCall.Expression); queryBuilder.Append(")"); }
public string GetSqlExpression(Expression expression, string contextName, QueryContext context) { return(SqlGeneratorExpressionTreeVisitor.GetSqlExpression(expression, this, contextName, context)); }