/** <inheritdoc /> */ protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression) { // In some cases of Join clause different handling should be introduced var joinClause = expression.ReferencedQuerySource as JoinClause; if (joinClause != null && ExpressionWalker.GetCacheQueryable(expression, false) == null) { var tableName = Aliases.GetTableAlias(expression); var fieldname = Aliases.GetFieldAlias(expression); ResultBuilder.AppendFormat("{0}.{1}", tableName, fieldname); } else if (joinClause != null && joinClause.InnerSequence is SubQueryExpression) { var subQueryExpression = (SubQueryExpression)joinClause.InnerSequence; base.Visit(subQueryExpression.QueryModel.SelectClause.Selector); } else { // Count, sum, max, min expect a single field or * // In other cases we need both parts of cache entry var format = _includeAllFields ? "{0}.*, {0}._KEY, {0}._VAL" : _useStar ? "{0}.*" : "{0}._KEY, {0}._VAL"; var tableName = Aliases.GetTableAlias(expression); ResultBuilder.AppendFormat(format, tableName); } return(expression); }
protected override Expression VisitMember(MemberExpression expression) { // Field hierarchy is flattened (Person.Address.Street is just Street), append as is, do not call Visit. // Property call (string.Length, DateTime.Month, etc). if (MethodVisitor.VisitPropertyCall(expression, this)) { return(expression); } // Special case: grouping if (VisitGroupByMember(expression.Expression)) { return(expression); } var queryable = ExpressionWalker.GetCacheQueryable(expression, false); if (queryable != null) { // Find where the projection comes from. expression = ExpressionWalker.GetProjectedMember(expression.Expression, expression.Member) ?? expression; var fieldName = GetEscapedFieldName(expression, queryable); ResultBuilder.AppendFormat("{0}.{1}", Aliases.GetTableAlias(expression), fieldName); } else { AppendParameter(ExpressionWalker.EvaluateExpression <object>(expression)); } return(expression); }
public override void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, int index) { base.VisitJoinClause(joinClause, queryModel, index); var subQuery = joinClause.InnerSequence as SubQueryExpression; if (subQuery != null) { var isOuter = subQuery.QueryModel.ResultOperators.OfType <DefaultIfEmptyResultOperator>().Any(); _builder.AppendFormat("{0} join (", isOuter ? "left outer" : "inner"); VisitQueryModel(subQuery.QueryModel, true); var alias = _aliases.GetTableAlias(subQuery.QueryModel.MainFromClause); _builder.AppendFormat(") as {0} on (", alias); } else { var queryable = ExpressionWalker.GetCacheQueryable(joinClause); var tableName = ExpressionWalker.GetTableNameWithSchema(queryable); var alias = _aliases.GetTableAlias(joinClause); _builder.AppendFormat("inner join {0} as {1} on (", tableName, alias); } BuildJoinCondition(joinClause.InnerKeySelector, joinClause.OuterKeySelector); _builder.Append(") "); }
/// <summary> /// Appends as clause. /// </summary> public StringBuilder AppendAsClause(StringBuilder builder, IFromClause clause) { Debug.Assert(builder != null); Debug.Assert(clause != null); var queryable = ExpressionWalker.GetCacheQueryable(clause); var tableName = ExpressionWalker.GetTableNameWithSchema(queryable); builder.AppendFormat("{0} as {1}", tableName, GetTableAlias(clause)); return(builder); }
/** <inheritdoc /> */ protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression) { // Count, sum, max, min expect a single field or * // In other cases we need both parts of cache entry var format = _useStar ? "{0}.*" : "{0}._key, {0}._val"; var tableName = Aliases.GetTableAlias(ExpressionWalker.GetCacheQueryable(expression)); ResultBuilder.AppendFormat(format, tableName); return(expression); }
/// <summary> /// Visits IEnumerable.Contains /// </summary> private void VisitContains(QueryModel subQueryModel, ContainsResultOperator contains) { ResultBuilder.Append('('); var fromExpression = subQueryModel.MainFromClause.FromExpression; var queryable = ExpressionWalker.GetCacheQueryable(fromExpression, false); if (queryable != null) { Visit(contains.Item); ResultBuilder.Append(" IN ("); if (_visitEntireSubQueryModel) { _modelVisitor.VisitQueryModel(subQueryModel, false, true); } else { _modelVisitor.VisitQueryModel(subQueryModel); } ResultBuilder.Append(')'); } else { var inValues = ExpressionWalker.EvaluateEnumerableValues(fromExpression).ToArray(); var hasNulls = inValues.Any(o => o == null); if (hasNulls) { ResultBuilder.Append('('); } Visit(contains.Item); ResultBuilder.Append(" IN ("); AppendInParameters(inValues); ResultBuilder.Append(')'); if (hasNulls) { ResultBuilder.Append(") OR "); Visit(contains.Item); ResultBuilder.Append(" IS NULL"); } } ResultBuilder.Append(')'); }
public override void VisitJoinClause(JoinClause joinClause, QueryModel queryModel, int index) { base.VisitJoinClause(joinClause, queryModel, index); var subQuery = joinClause.InnerSequence as SubQueryExpression; if (subQuery != null) { var isOuter = subQuery.QueryModel.ResultOperators.OfType <DefaultIfEmptyResultOperator>().Any(); _builder.AppendFormat("{0} join (", isOuter ? "left outer" : "inner"); VisitQueryModel(subQuery.QueryModel, true); var queryable = ExpressionWalker.GetCacheQueryable(subQuery.QueryModel.MainFromClause); var alias = _aliases.GetTableAlias(queryable); _builder.AppendFormat(") as {0} on (", alias); } else { var innerExpr = joinClause.InnerSequence as ConstantExpression; if (innerExpr == null) { throw new NotSupportedException("Unexpected JOIN inner sequence (subqueries are not supported): " + joinClause.InnerSequence); } if (!(innerExpr.Value is ICacheQueryable)) { throw new NotSupportedException("Unexpected JOIN inner sequence " + "(only results of cache.ToQueryable() are supported): " + innerExpr.Value); } var queryable = ExpressionWalker.GetCacheQueryable(joinClause); var tableName = ExpressionWalker.GetTableNameWithSchema(queryable); _builder.AppendFormat("inner join {0} as {1} on (", tableName, _aliases.GetTableAlias(tableName)); } BuildJoinCondition(joinClause.InnerKeySelector, joinClause.OuterKeySelector); _builder.Append(") "); }
protected override Expression VisitMember(MemberExpression expression) { // Field hierarchy is flattened (Person.Address.Street is just Street), append as is, do not call Visit. // Special case: string.Length if (expression.Member == MethodVisitor.StringLength) { ResultBuilder.Append("length("); VisitMember((MemberExpression)expression.Expression); ResultBuilder.Append(")"); return(expression); } // Special case: grouping if (VisitGroupByMember(expression.Expression)) { return(expression); } var queryable = ExpressionWalker.GetCacheQueryable(expression, false); if (queryable != null) { var fieldName = GetFieldName(expression, queryable); ResultBuilder.AppendFormat("{0}.{1}", Aliases.GetTableAlias(expression), fieldName); } else { AppendParameter(RegisterEvaluatedParameter(expression)); } return(expression); }