protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var returnType = methodCall.Method.ReturnType; var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); if (sequence.SqlQuery != buildInfo.SqlQuery) { if (sequence is JoinBuilder.GroupJoinSubQueryContext) { var ctx = new CountContext(buildInfo.Parent, sequence, returnType) { SqlQuery = ((JoinBuilder.GroupJoinSubQueryContext)sequence).GetCounter(methodCall) }; ctx.Sql = ctx.SqlQuery; ctx.FieldIndex = ctx.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, ctx.SqlQuery), "cnt"); return(ctx); } if (sequence is GroupByBuilder.GroupByContext) { return(new CountContext(buildInfo.Parent, sequence, returnType) { Sql = SqlFunction.CreateCount(returnType, sequence.SqlQuery), FieldIndex = -1 }); } } if (sequence.SqlQuery.Select.IsDistinct || sequence.SqlQuery.Select.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null || !sequence.SqlQuery.GroupBy.IsEmpty) { sequence.ConvertToIndex(null, 0, ConvertFlags.Key); sequence = new SubQueryContext(sequence); } if (sequence.SqlQuery.OrderBy.Items.Count > 0) { if (sequence.SqlQuery.Select.TakeValue == null && sequence.SqlQuery.Select.SkipValue == null) { sequence.SqlQuery.OrderBy.Items.Clear(); } else { sequence = new SubQueryContext(sequence); } } var context = new CountContext(buildInfo.Parent, sequence, returnType); context.Sql = context.SqlQuery; context.FieldIndex = context.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, context.SqlQuery), "cnt"); return(context); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); if (sequence.SqlQuery.Select.IsDistinct || sequence.SqlQuery.Select.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null) { sequence.ConvertToIndex(null, 0, ConvertFlags.Key); sequence = new SubQueryContext(sequence); } if (sequence.SqlQuery.OrderBy.Items.Count > 0) { if (sequence.SqlQuery.Select.TakeValue == null && sequence.SqlQuery.Select.SkipValue == null) { sequence.SqlQuery.OrderBy.Items.Clear(); } else { sequence = new SubQueryContext(sequence); } } if (methodCall.Arguments.Count == 2) { var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); sequence = parser.ParseWhere(sequence, condition, true); sequence.SetAlias(condition.Parameters[0].Name); } var context = new CountConext(sequence, methodCall.Method.ReturnType); context.FieldIndex = context.SqlQuery.Select.Add(SqlFunction.CreateCount(methodCall.Method.ReturnType, context.SqlQuery), "cnt"); return(context); }
private IQueryExpression ConvertEnumerable(MethodCallExpression call) { if (AggregationBuilder.MethodNames.Contains(call.Method.Name)) { if (call.Arguments[0].NodeType == ExpressionType.Call) { var arg = (MethodCallExpression)call.Arguments[0]; if (arg.Method.Name == "Select") { if (arg.Arguments[0].NodeType != ExpressionType.Call) { var l = (LambdaExpression)arg.Arguments[1].Unwrap(); var largs = l.Type.GetGenericArgumentsEx(); if (largs.Length == 2) { var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); var sql = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); return(new SqlFunction(call.Type, call.Method.Name, sql)); } } } } } if (call.Arguments[0].NodeType == ExpressionType.Call) { var ctx = Builder.GetSubQuery(this, call); if (Builder.DataContextInfo.SqlProviderFlags.IsSubQueryColumnSupported) { return(ctx.Select); } var join = ctx.Select.CrossApply(); Select.From.Tables.First.Value.Joins.AddLast(join.JoinedTable); return(ctx.Select.Select.Columns[0]); } var args = new IQueryExpression[call.Arguments.Count - 1]; if (CountBuilder.MethodNames.Contains(call.Method.Name)) { if (args.Length > 0) { throw new InvalidOperationException(); } return(SqlFunction.CreateCount(call.Type, Select)); } if (call.Arguments.Count > 1) { for (var i = 1; i < call.Arguments.Count; i++) { var ex = call.Arguments[i].Unwrap(); var lambdaExpression = ex as LambdaExpression; if (lambdaExpression != null) { var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, lambdaExpression); args[i - 1] = Builder.ConvertToSql(ctx, lambdaExpression.Body, true); Builder.ReplaceParent(ctx, p); } else { throw new NotImplementedException(); } } } else { args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); } return(new SqlFunction(call.Type, call.Method.Name, args)); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var returnType = methodCall.Method.ReturnType; var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]) { CreateSubQuery = true }); if (sequence.SelectQuery != buildInfo.SelectQuery) { if (sequence is JoinBuilder.GroupJoinSubQueryContext) { var ctx = new CountContext(buildInfo.Parent, sequence, returnType) { SelectQuery = sequence.SelectQuery //((JoinBuilder.GroupJoinSubQueryContext)sequence).GetCounter(methodCall) }; ctx.Sql = ctx.SelectQuery; ctx.FieldIndex = ctx.SelectQuery.Select.Add(SqlFunction.CreateCount(returnType, ctx.SelectQuery), "cnt"); return(ctx); } if (sequence is GroupByBuilder.GroupByContext) { // var ctx = new CountContext(buildInfo.Parent, sequence, returnType); // // ctx.Sql = ctx.SelectQuery; // ctx.FieldIndex = ctx.SelectQuery.Select.Add(SqlFunction.CreateCount(returnType, ctx.SelectQuery), "cnt"); // // return ctx; // return new CountContext(buildInfo.Parent, sequence, returnType) // { // Sql = SqlFunction.CreateCount(returnType, sequence.SelectQuery), // FieldIndex = -1 // }; } } if (sequence.SelectQuery.Select.IsDistinct || sequence.SelectQuery.Select.TakeValue != null || sequence.SelectQuery.Select.SkipValue != null) { sequence.ConvertToIndex(null, 0, ConvertFlags.Key); sequence = new SubQueryContext(sequence); } else if (!sequence.SelectQuery.GroupBy.IsEmpty) { if (!builder.DataContext.SqlProviderFlags.IsSybaseBuggyGroupBy) { sequence.SelectQuery.Select.Add(new SqlValue(0)); } else { foreach (var item in sequence.SelectQuery.GroupBy.Items) { sequence.SelectQuery.Select.Add(item); } } sequence = new SubQueryContext(sequence); } if (sequence.SelectQuery.OrderBy.Items.Count > 0) { if (sequence.SelectQuery.Select.TakeValue == null && sequence.SelectQuery.Select.SkipValue == null) { sequence.SelectQuery.OrderBy.Items.Clear(); } else { sequence = new SubQueryContext(sequence); } } var context = new CountContext(buildInfo.Parent, sequence, returnType); context.Sql = context.SelectQuery; context.FieldIndex = context.SelectQuery.Select.Add(SqlFunction.CreateCount(returnType, context.SelectQuery), "cnt"); return(context); }
ISqlExpression ConvertEnumerable(MethodCallExpression call) { if (call.IsAggregate(Builder.MappingSchema)) { if (call.Arguments[0].NodeType == ExpressionType.Call) { var arg = (MethodCallExpression)call.Arguments[0]; if (arg.Method.Name == "Select") { var arg0 = arg.Arguments[0].SkipPathThrough(); if (arg0.NodeType != ExpressionType.Call) { var l = (LambdaExpression)arg.Arguments[1].Unwrap(); var largs = l.Type.GetGenericArgumentsEx(); if (largs.Length == 2) { var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); var sql = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); return(new SqlFunction(call.Type, call.Method.Name, sql)); } } } } } if (call.Arguments[0].NodeType == ExpressionType.Call) { var ctx = Builder.GetSubQuery(this, call); if (Builder.DataContext.SqlProviderFlags.IsSubQueryColumnSupported) { return(ctx.SelectQuery); } var join = ctx.SelectQuery.CrossApply(); SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable); return(ctx.SelectQuery.Select.Columns[0]); } var args = new ISqlExpression[call.Arguments.Count - 1]; if (CountBuilder.MethodNames.Contains(call.Method.Name)) { if (args.Length > 0) { throw new InvalidOperationException(); } return(SqlFunction.CreateCount(call.Type, SelectQuery)); } var attribute = Builder.MappingSchema.GetAttribute <Sql.ExpressionAttribute>(call.Method.DeclaringType, call.Method, c => c.Configuration); if (attribute != null) { var expr = attribute.GetExpression(Builder.DataContext, SelectQuery, call, e => { var ex = e.Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); var res = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); return(res); } else { return(Builder.ConvertToSql(_element, ex, true)); } }); if (expr != null) { return(expr); } } if (call.Arguments.Count > 1) { for (var i = 1; i < call.Arguments.Count; i++) { var ex = call.Arguments[i].Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); args[i - 1] = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); } else { args[i - 1] = Builder.ConvertToSql(_element, ex, true); } } } else { args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); } if (attribute != null) { return(attribute.GetExpression(call.Method, args)); } return(new SqlFunction(call.Type, call.Method.Name, args)); }
ISqlExpression ConvertEnumerable(MethodCallExpression call) { var expr = call; // if (AggregationBuilder.MethodNames.Contains(expr.Method.Name)) // while (arg.NodeType == ExpressionType.Call && ((MethodCallExpression)arg).Method.Name == "Select") // arg = ((MethodCallExpression)arg).Arguments[0]; if (call.Arguments[0].NodeType == ExpressionType.Call) { var ctx = Builder.GetSubQuery(this, call); if (Builder.SqlProvider.IsSubQueryColumnSupported) { return(ctx.SqlQuery); } var join = ctx.SqlQuery.CrossApply(); SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); return(ctx.SqlQuery.Select.Columns[0]); } var args = new ISqlExpression[call.Arguments.Count - 1]; if (CountBuilder.MethodNames.Contains(call.Method.Name)) { if (args.Length > 0) { throw new InvalidOperationException(); /* * var ctx = _element; * var l = (LambdaExpression)call.Arguments[1].Unwrap(); * var cnt = Builder.BuildWhere(Parent, ctx, l, false); * var sql = cnt.SqlQuery.Clone((_ => !(_ is SqlParameter))); * * sql.ParentSql = SqlQuery; * sql.Select.Columns.Clear(); * * if (ctx == cnt) * ctx.SqlQuery.Where.SearchCondition.Conditions.RemoveAt(ctx.SqlQuery.Where.SearchCondition.Conditions.Count - 1); * * if (Builder.SqlProvider.IsSubQueryColumnSupported && Builder.SqlProvider.IsCountSubQuerySupported) * { * for (var i = 0; i < sql.GroupBy.Items.Count; i++) * { * var item1 = sql.GroupBy.Items[i]; * var item2 = SqlQuery.GroupBy.Items[i]; * var pr = Builder.Convert(this, new SqlQuery.Predicate.ExprExpr(item1, SqlQuery.Predicate.Operator.Equal, item2)); * * sql.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, pr)); * } * * sql.GroupBy.Items.Clear(); * sql.Select.Expr(SqlFunction.CreateCount(call.Type, sql)); * * return sql; * } * * var join = sql.WeakLeftJoin(); * * SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); * * for (var i = 0; i < sql.GroupBy.Items.Count; i++) * { * var item1 = sql.GroupBy.Items[i]; * var item2 = SqlQuery.GroupBy.Items[i]; * var col = sql.Select.Columns[sql.Select.Add(item1)]; * var pr = Builder.Convert(this, new SqlQuery.Predicate.ExprExpr(col, SqlQuery.Predicate.Operator.Equal, item2)); * * join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, pr)); * } * * return new SqlFunction(call.Type, "Count", sql.Select.Columns[0]); */ } return(SqlFunction.CreateCount(call.Type, SqlQuery)); } if (call.Arguments.Count > 1) { for (var i = 1; i < call.Arguments.Count; i++) { var ex = call.Arguments[i].Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); _element.Parent = p; args[i - 1] = Builder.ConvertToSql(ctx, l.Body.Unwrap()); } else { throw new NotImplementedException(); } } } else { args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); } return(new SqlFunction(call.Type, call.Method.Name, args)); }
ISqlExpression ParseEnumerable(MethodCallExpression expr) { var args = new ISqlExpression[expr.Arguments.Count - 1]; if (expr.Method.Name == "Count") { if (args.Length > 0) { var ctx = _element; var l = (LambdaExpression)expr.Arguments[1].Unwrap(); var cnt = Parser.ParseWhere(ctx, l, false); var sql = cnt.SqlQuery.Clone((_ => !(_ is SqlParameter))); sql.ParentSql = SqlQuery; sql.Select.Columns.Clear(); if (ctx == cnt) ctx.SqlQuery.Where.SearchCondition.Conditions.RemoveAt(ctx.SqlQuery.Where.SearchCondition.Conditions.Count - 1); if (Parser.SqlProvider.IsSubQueryColumnSupported && Parser.SqlProvider.IsCountSubQuerySupported) { for (var i = 0; i < sql.GroupBy.Items.Count; i++) { var item1 = sql.GroupBy.Items[i]; var item2 = SqlQuery.GroupBy.Items[i]; var pr = Parser.Convert(this, new SqlQuery.Predicate.ExprExpr(item1, SqlQuery.Predicate.Operator.Equal, item2)); sql.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, pr)); } sql.GroupBy.Items.Clear(); sql.Select.Expr(SqlFunction.CreateCount(expr.Type, sql)); return sql; } var join = sql.WeakLeftJoin(); SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); for (var i = 0; i < sql.GroupBy.Items.Count; i++) { var item1 = sql.GroupBy.Items[i]; var item2 = SqlQuery.GroupBy.Items[i]; var col = sql.Select.Columns[sql.Select.Add(item1)]; var pr = Parser.Convert(this, new SqlQuery.Predicate.ExprExpr(col, SqlQuery.Predicate.Operator.Equal, item2)); join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, pr)); } return new SqlFunction(expr.Type, "Count", sql.Select.Columns[0]); } return SqlFunction.CreateCount(expr.Type, SqlQuery); } if (expr.Arguments.Count > 1) { for (var i = 1; i < expr.Arguments.Count; i++) { var ex = expr.Arguments[i].Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var ctx = new PathThroughContext(_element, l); args[i - 1] = Parser.ParseExpression(ctx, l.Body.Unwrap()); } else { throw new NotImplementedException(); } } } else { if (expr.Arguments[0].NodeType == ExpressionType.Call) { var arg = expr.Arguments[0]; if (arg.NodeType == ExpressionType.Call) { var call = (MethodCallExpression)arg; if (call.Method.Name == "Select" && call.IsQueryableMethod((seq,l) => { if (seq.NodeType == ExpressionType.Parameter) { args = new[] { Parser.ParseExpression(this, l.Body) }; } return false; })) {} } } else //if (query.ElementSource is QuerySource.Scalar) { args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); //var scalar = (QuerySource.Scalar)query.ElementSource; //args = new[] { scalar.GetExpressions(this)[0] }; } } return new SqlFunction(expr.Type, expr.Method.Name, args); }