Пример #1
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.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null)
            {
                sequence = new SubQueryContext(sequence);
            }

            var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var order  = new PathThroughContext(sequence, lambda);
            var body   = lambda.Body.Unwrap();
            var sql    = parser.ParseExpressions(order, body, ConvertFlags.Key);

            if (!methodCall.Method.Name.StartsWith("Then"))
            {
                sequence.SqlQuery.OrderBy.Items.Clear();
            }

            foreach (var expr in sql)
            {
                var e = expr.Sql;

                if (e is SqlQuery.SearchCondition)
                {
                    if (e.CanBeNull())
                    {
                        var notExpr = new SqlQuery.SearchCondition
                        {
                            Conditions = { new SqlQuery.Condition(true, new SqlQuery.Predicate.Expr(e, e.Precedence)) }
                        };

                        e = parser.Convert(sequence, new SqlFunction(e.SystemType, "CASE", e, new SqlValue(1), notExpr, new SqlValue(0), new SqlValue(null)));
                    }
                    else
                    {
                        e = parser.Convert(sequence, new SqlFunction(e.SystemType, "CASE", e, new SqlValue(1), new SqlValue(0)));
                    }
                }

                sequence.SqlQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
            }

            return(sequence);
        }
		public IParseContext ParseWhere(IParseContext sequence, LambdaExpression condition, bool checkForSubQuery)
		{
			var makeHaving = false;

			var  ctx  = new PathThroughContext(sequence, condition);
			var  expr = condition.Body.Unwrap();

			if (checkForSubQuery && CheckSubQueryForWhere(ctx, expr, out makeHaving))
			{
				sequence = new SubQueryContext(sequence);
				ctx      = new PathThroughContext(sequence, condition);
			}

			ParseSearchCondition(
				ctx,
				expr,
				makeHaving ?
					ctx.SqlQuery.Having.SearchCondition.Conditions :
					ctx.SqlQuery.Where. SearchCondition.Conditions);

			return sequence;
		}
Пример #3
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.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null)
				sequence = new SubQueryContext(sequence);

			var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap();
			var order  = new PathThroughContext(sequence, lambda);
			var body   = lambda.Body.Unwrap();
			var sql    = parser.ParseExpressions(order, body, ConvertFlags.Key);

			if (!methodCall.Method.Name.StartsWith("Then"))
				sequence.SqlQuery.OrderBy.Items.Clear();

			foreach (var expr in sql)
			{
				var e = expr.Sql;

				if (e is SqlQuery.SearchCondition)
				{
					if (e.CanBeNull())
					{
						var notExpr = new SqlQuery.SearchCondition
						{
							Conditions = { new SqlQuery.Condition(true, new SqlQuery.Predicate.Expr(e, e.Precedence)) }
						};

						e = parser.Convert(sequence, new SqlFunction(e.SystemType, "CASE", e, new SqlValue(1), notExpr, new SqlValue(0), new SqlValue(null)));
					}
					else
						e = parser.Convert(sequence, new SqlFunction(e.SystemType, "CASE", e, new SqlValue(1), new SqlValue(0)));
				}

				sequence.SqlQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
			}

			return sequence;
		}
Пример #4
0
		protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery)
		{
			var isGroup      = methodCall.Method.Name == "GroupJoin";
			var outerContext = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery);
			var innerContext = parser.ParseSequence(parent, methodCall.Arguments[1], new SqlQuery());

			outerContext = new SubQueryContext(outerContext);
			innerContext = new SubQueryContext(innerContext);

			var join = innerContext.SqlQuery.InnerJoin();
			var sql  = new SqlQuery();

			sql.From.Table(outerContext.SqlQuery, join);

			var selector = (LambdaExpression)methodCall.Arguments[4].Unwrap();

			outerContext.SetAlias(selector.Parameters[0].Name);
			innerContext.SetAlias(selector.Parameters[1].Name);

			var outerKeyLambda = ((LambdaExpression)methodCall.Arguments[2].Unwrap());
			var innerKeyLambda = ((LambdaExpression)methodCall.Arguments[3].Unwrap());

			var outerKeySelector = outerKeyLambda.Body.Unwrap();
			var innerKeySelector = innerKeyLambda.Body.Unwrap();

			var outerKeyContext = new PathThroughContext(outerContext, outerKeyLambda);
			var innerKeyContext = new PathThroughContext(innerContext, innerKeyLambda);

			if (outerKeySelector.NodeType == ExpressionType.New)
			{
				var new1 = (NewExpression)outerKeySelector;
				var new2 = (NewExpression)innerKeySelector;

				for (var i = 0; i < new1.Arguments.Count; i++)
				{
					var arg1 = new1.Arguments[i];
					var arg2 = new2.Arguments[i];

					var predicate = parser.ParseObjectComparison(ExpressionType.Equal, outerKeyContext, arg1, innerKeyContext, arg2);

					if (predicate != null)
						join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
					else
						join
							.Expr(parser.ParseExpression(outerKeyContext, arg1)).Equal
							.Expr(parser.ParseExpression(innerKeyContext, arg2));
				}
			}
			else if (outerKeySelector.NodeType == ExpressionType.MemberInit)
			{
				var mi1 = (MemberInitExpression)outerKeySelector;
				var mi2 = (MemberInitExpression)innerKeySelector;

				for (var i = 0; i < mi1.Bindings.Count; i++)
				{
					if (mi1.Bindings[i].Member != mi2.Bindings[i].Member)
						throw new LinqException(string.Format("List of member inits does not match for entity type '{0}'.", outerKeySelector.Type));

					var arg1 = ((MemberAssignment)mi1.Bindings[i]).Expression;
					var arg2 = ((MemberAssignment)mi2.Bindings[i]).Expression;

					var predicate = parser.ParseObjectComparison(ExpressionType.Equal, outerKeyContext, arg1, innerKeyContext, arg2);

					if (predicate != null)
						join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
					else
						join
							.Expr(parser.ParseExpression(outerKeyContext, arg1)).Equal
							.Expr(parser.ParseExpression(innerKeyContext, arg2));
				}
			}
			else
			{
				var predicate = parser.ParseObjectComparison(
					ExpressionType.Equal,
					outerKeyContext, outerKeySelector,
					innerKeyContext, innerKeySelector);

				if (predicate != null)
					join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
				else
					join
						.Expr(parser.ParseExpression(outerKeyContext, outerKeySelector)).Equal
						.Expr(parser.ParseExpression(innerKeyContext, innerKeySelector));
			}

			return isGroup ?
				new GroupJoinContext(selector, outerContext, innerContext, sql) :
				new      JoinContext(selector, outerContext, innerContext, sql);
		}
Пример #5
0
        protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery)
        {
            var isGroup      = methodCall.Method.Name == "GroupJoin";
            var outerContext = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery);
            var innerContext = parser.ParseSequence(parent, methodCall.Arguments[1], new SqlQuery());

            outerContext = new SubQueryContext(outerContext);
            innerContext = new SubQueryContext(innerContext);

            var join = innerContext.SqlQuery.InnerJoin();
            var sql  = new SqlQuery();

            sql.From.Table(outerContext.SqlQuery, join);

            var selector = (LambdaExpression)methodCall.Arguments[4].Unwrap();

            outerContext.SetAlias(selector.Parameters[0].Name);
            innerContext.SetAlias(selector.Parameters[1].Name);

            var outerKeyLambda = ((LambdaExpression)methodCall.Arguments[2].Unwrap());
            var innerKeyLambda = ((LambdaExpression)methodCall.Arguments[3].Unwrap());

            var outerKeySelector = outerKeyLambda.Body.Unwrap();
            var innerKeySelector = innerKeyLambda.Body.Unwrap();

            var outerKeyContext = new PathThroughContext(outerContext, outerKeyLambda);
            var innerKeyContext = new PathThroughContext(innerContext, innerKeyLambda);

            if (outerKeySelector.NodeType == ExpressionType.New)
            {
                var new1 = (NewExpression)outerKeySelector;
                var new2 = (NewExpression)innerKeySelector;

                for (var i = 0; i < new1.Arguments.Count; i++)
                {
                    var arg1 = new1.Arguments[i];
                    var arg2 = new2.Arguments[i];

                    var predicate = parser.ParseObjectComparison(ExpressionType.Equal, outerKeyContext, arg1, innerKeyContext, arg2);

                    if (predicate != null)
                    {
                        join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
                    }
                    else
                    {
                        join
                        .Expr(parser.ParseExpression(outerKeyContext, arg1)).Equal
                        .Expr(parser.ParseExpression(innerKeyContext, arg2));
                    }
                }
            }
            else if (outerKeySelector.NodeType == ExpressionType.MemberInit)
            {
                var mi1 = (MemberInitExpression)outerKeySelector;
                var mi2 = (MemberInitExpression)innerKeySelector;

                for (var i = 0; i < mi1.Bindings.Count; i++)
                {
                    if (mi1.Bindings[i].Member != mi2.Bindings[i].Member)
                    {
                        throw new LinqException(string.Format("List of member inits does not match for entity type '{0}'.", outerKeySelector.Type));
                    }

                    var arg1 = ((MemberAssignment)mi1.Bindings[i]).Expression;
                    var arg2 = ((MemberAssignment)mi2.Bindings[i]).Expression;

                    var predicate = parser.ParseObjectComparison(ExpressionType.Equal, outerKeyContext, arg1, innerKeyContext, arg2);

                    if (predicate != null)
                    {
                        join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
                    }
                    else
                    {
                        join
                        .Expr(parser.ParseExpression(outerKeyContext, arg1)).Equal
                        .Expr(parser.ParseExpression(innerKeyContext, arg2));
                    }
                }
            }
            else
            {
                var predicate = parser.ParseObjectComparison(
                    ExpressionType.Equal,
                    outerKeyContext, outerKeySelector,
                    innerKeyContext, innerKeySelector);

                if (predicate != null)
                {
                    join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate));
                }
                else
                {
                    join
                    .Expr(parser.ParseExpression(outerKeyContext, outerKeySelector)).Equal
                    .Expr(parser.ParseExpression(innerKeyContext, innerKeySelector));
                }
            }

            return(isGroup ?
                   new GroupJoinContext(selector, outerContext, innerContext, sql) :
                   new      JoinContext(selector, outerContext, innerContext, sql));
        }
Пример #6
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);
			}