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; }
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; }
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; }
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; }
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; }
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); }