Пример #1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var query    = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery()));
            var except   = query.SqlQuery;

            sequence = new SubQueryContext(sequence);

            var sql = sequence.SqlQuery;

            except.ParentSql = sql;

            if (methodCall.Method.Name == "Except")
                sql.Where.Not.Exists(except);
            else
                sql.Where.Exists(except);

            var keys1 = sequence.ConvertToSql(null, 0, ConvertFlags.Key);
            var keys2 = query.   ConvertToSql(null, 0, ConvertFlags.Key);

            if (keys1.Length != keys2.Length)
                throw new InvalidOperationException();

            for (var i = 0; i < keys1.Length; i++)
            {
                except.Where
                    .Expr(keys1[i].Sql)
                    .Equal
                    .Expr(keys2[i].Sql);
            }

            return sequence;
        }
Пример #2
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            if (sequence.SelectQuery.Select.TakeValue != null || sequence.SelectQuery.Select.SkipValue != null)
                sequence = new SubQueryContext(sequence);

            var lambda  = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var sparent = sequence.Parent;
            var order   = new ExpressionContext(buildInfo.Parent, sequence, lambda);
            var body    = lambda.Body.Unwrap();
            var sql     = builder.ConvertExpressions(order, body, ConvertFlags.Key);

            builder.ReplaceParent(order, sparent);

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

            foreach (var expr in sql)
            {
                var e = builder.ConvertSearchCondition(sequence, expr.Sql);
                sequence.SelectQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
            }

            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);
			var sql      = sequence.SqlQuery;

			if (sql.Select.TakeValue != null || sql.Select.SkipValue != null)
				sequence = new SubQueryContext(sequence);

			sequence.SqlQuery.Select.IsDistinct = true;

			return sequence;
		}
Пример #4
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var sql      = sequence.SqlQuery;

            if (sql.Select.TakeValue != null || sql.Select.SkipValue != null)
                sequence = new SubQueryContext(sequence);

            sequence.SqlQuery.Select.IsDistinct = true;
            sequence.ConvertToIndex(null, 0, ConvertFlags.All);

            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;
		}
Пример #6
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;
		}
Пример #7
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);
		}