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.All); 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 lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var context = new AggregationContext(sequence, lambda, methodCall.Method.ReturnType); context.FieldIndex = context.SqlQuery.Select.Add( new SqlFunction( methodCall.Type, methodCall.Method.Name, parser.ParseExpression(context, context.Lambda.Body.Unwrap()))); return(context); } else { var context = new AggregationContext(sequence, null, methodCall.Method.ReturnType); context.FieldIndex = context.SqlQuery.Select.Add( new SqlFunction( methodCall.Type, methodCall.Method.Name, sequence.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray())); return(context); } }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var arg = methodCall.Arguments[1].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) arg = ((LambdaExpression)arg).Body.Unwrap(); var expr = parser.ParseExpression(sequence, arg); if (methodCall.Method.Name == "Take") { ParseTake(parser, sequence, expr); } else { ParseSkip(parser, sequence, sequence.SqlQuery.Select.SkipValue, expr); } return sequence; }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var arg = methodCall.Arguments[1].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) { arg = ((LambdaExpression)arg).Body.Unwrap(); } var expr = parser.ParseExpression(sequence, arg); if (methodCall.Method.Name == "Take") { ParseTake(parser, sequence, expr); } else { ParseSkip(parser, sequence, sequence.SqlQuery.Select.SkipValue, expr); } 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); }
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)); }