Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
            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));
            }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
            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));
            }
Exemplo n.º 6
0
            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));
            }
Exemplo n.º 7
0
			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);
			}