protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var defaultValue = methodCall.Arguments.Count == 1 ? null : methodCall.Arguments[1].Unwrap(); return new DefaultIfEmptyContext(sequence, defaultValue); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var selector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); sequence.SetAlias(selector.Parameters[0].Name); var body = selector.Body.Unwrap(); // .Select(p => p) // //if (body == selector.Parameters[0]) // return sequence; switch (body.NodeType) { case ExpressionType.Parameter: break; default: sequence = CheckSubQueryForSelect(sequence); break; } return(selector.Parameters.Count == 1 ? new SelectContext(selector, sequence) : new SelectContext2(selector, sequence)); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var defaultValue = methodCall.Arguments.Count == 1 ? null : methodCall.Arguments[1].Unwrap(); return(new DefaultIfEmptyContext(sequence, defaultValue)); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var result = parser.ParseWhere(sequence, condition, true); result.SetAlias(condition.Parameters[0].Name); return(result); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var condition = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var result = parser.ParseWhere(sequence, condition, true); result.SetAlias(condition.Parameters[0].Name); return result; }
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 IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { var sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var sequenceExpr = methodCall.Arguments[0]; var groupingType = methodCall.Type.GetGenericArguments()[0]; var keySelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var elementSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); if (methodCall.Arguments[0].NodeType == ExpressionType.Call) { var call = (MethodCallExpression)methodCall.Arguments[0]; if (call.Method.Name == "Select") { var type = ((LambdaExpression)call.Arguments[1].Unwrap()).Body.Type; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ExpressionParser.GroupSubQuery<,>)) { sequence = new SubQueryContext(sequence); } } } var key = new KeyContext(keySelector, sequence); var groupSql = parser.ParseExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); if (groupSql.Any(_ => !(_.Sql is SqlField || _.Sql is SqlQuery.Column))) { sequence = new SubQueryContext(sequence); key = new KeyContext(keySelector, sequence); groupSql = parser.ParseExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); } sequence.SqlQuery.GroupBy.Items.Clear(); foreach (var sql in groupSql) sequence.SqlQuery.GroupBy.Expr(sql.Sql); new QueryVisitor().Visit(sequence.SqlQuery.From, e => { if (e.ElementType == QueryElementType.JoinedTable) { var jt = (SqlQuery.JoinedTable)e; if (jt.JoinType == SqlQuery.JoinType.Inner) jt.IsWeak = false; } }); var element = new SelectContext (elementSelector, sequence); var groupBy = new GroupByContext(sequenceExpr, groupingType, sequence, key, element); return groupBy; }
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 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); 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 sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); 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 take = 0; if (parser.SubQueryParsingCounter == 0 || parser.SqlProvider.IsSubQueryTakeSupported) { switch (methodCall.Method.Name) { case "First": case "FirstOrDefault": take = 1; break; case "Single": case "SingleOrDefault": if (parser.SubQueryParsingCounter == 0) { take = 2; } break; } } if (take != 0) { parser.ParseTake(sequence, new SqlValue(take)); } //sequence.BuildExpression(null, 0); return(new FirstSingleContext(sequence, methodCall.Method.Name)); }
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 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); 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); }
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) { return(parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery)); }
protected override IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery) { return parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); }
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 sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var collectionSelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var resultSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); //if (collectionSelector.Parameters[0] == collectionSelector.Body.Unwrap()) //{ // return resultSelector == null ? sequence : new SelectContext(resultSelector, sequence, sequence); //} var context = new SelectManyContext(collectionSelector, sequence); var expr = collectionSelector.Body.Unwrap(); var crossApply = null != expr.Find(e => e == collectionSelector.Parameters[0]); /* * if (expr.NodeType == ExpressionType.Call) * { * var call = (MethodCallExpression)collectionSelector.Body; * * if (call.IsQueryable("DefaultIfEmpty")) * { * leftJoin = true; * expr = call.Arguments[0]; * } * } */ parser.SubQueryParsingCounter++; var collection = parser.ParseSequence(context, expr, new SqlQuery()); parser.SubQueryParsingCounter--; var leftJoin = collection is DefaultIfEmptyParser.DefaultIfEmptyContext; var sql = collection.SqlQuery; if (!leftJoin && crossApply) { if (sql.GroupBy.IsEmpty && sql.Select.Columns.Count == 0 && !sql.Select.HasModifier && sql.Where.IsEmpty && !sql.HasUnion && sql.From.Tables.Count == 1) { crossApply = false; } } if (!leftJoin && !crossApply) { sequence.SqlQuery.From.Table(sql); //sql.ParentSql = sequence.SqlQuery; var col = (IParseContext) new SubQueryContext(collection, sequence.SqlQuery, true); return(new SelectContext(resultSelector, sequence, col)); } //if (crossApply) { if (sql.GroupBy.IsEmpty && sql.Select.Columns.Count == 0 && !sql.Select.HasModifier && //!sql.Where.IsEmpty && !sql.HasUnion && sql.From.Tables.Count == 1) { var join = leftJoin ? SqlQuery.LeftJoin(sql) : SqlQuery.InnerJoin(sql); join.JoinedTable.Condition.Conditions.AddRange(sql.Where.SearchCondition.Conditions); sql.Where.SearchCondition.Conditions.Clear(); if (collection is TableParser.TableContext) { var collectionParent = collection.Parent as TableParser.TableContext; if (collectionParent != null) { var ts = (SqlQuery.TableSource) new QueryVisitor().Find(sequence.SqlQuery.From, e => { if (e.ElementType == QueryElementType.TableSource) { var t = (SqlQuery.TableSource)e; return(t.Source == collectionParent.SqlTable); } return(false); }); ts.Joins.Add(join.JoinedTable); } else { sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); } } else { sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); //collection.SqlQuery = sequence.SqlQuery; } //sql.ParentSql = sequence.SqlQuery; var col = (IParseContext) new SubQueryContext(collection, sequence.SqlQuery, false); return(new SelectContext(resultSelector, sequence, col)); } } throw new LinqException("Sequence '{0}' cannot be converted to SQL.", expr); }
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 sequence = parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery); var collectionSelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var resultSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); //if (collectionSelector.Parameters[0] == collectionSelector.Body.Unwrap()) //{ // return resultSelector == null ? sequence : new SelectContext(resultSelector, sequence, sequence); //} var context = new SelectManyContext(collectionSelector, sequence); var expr = collectionSelector.Body.Unwrap(); var crossApply = null != expr.Find(e => e == collectionSelector.Parameters[0]); /* if (expr.NodeType == ExpressionType.Call) { var call = (MethodCallExpression)collectionSelector.Body; if (call.IsQueryable("DefaultIfEmpty")) { leftJoin = true; expr = call.Arguments[0]; } } */ parser.SubQueryParsingCounter++; var collection = parser.ParseSequence(context, expr, new SqlQuery()); parser.SubQueryParsingCounter--; var leftJoin = collection is DefaultIfEmptyParser.DefaultIfEmptyContext; var sql = collection.SqlQuery; if (!leftJoin && crossApply) { if (sql.GroupBy.IsEmpty && sql.Select.Columns.Count == 0 && !sql.Select.HasModifier && sql.Where.IsEmpty && !sql.HasUnion && sql.From.Tables.Count == 1) { crossApply = false; } } if (!leftJoin && !crossApply) { sequence.SqlQuery.From.Table(sql); //sql.ParentSql = sequence.SqlQuery; var col = (IParseContext)new SubQueryContext(collection, sequence.SqlQuery, true); return new SelectContext(resultSelector, sequence, col); } //if (crossApply) { if (sql.GroupBy.IsEmpty && sql.Select.Columns.Count == 0 && !sql.Select.HasModifier && //!sql.Where.IsEmpty && !sql.HasUnion && sql.From.Tables.Count == 1) { var join = leftJoin ? SqlQuery.LeftJoin(sql) : SqlQuery.InnerJoin(sql); join.JoinedTable.Condition.Conditions.AddRange(sql.Where.SearchCondition.Conditions); sql.Where.SearchCondition.Conditions.Clear(); if (collection is TableParser.TableContext) { var collectionParent = collection.Parent as TableParser.TableContext; if (collectionParent != null) { var ts = (SqlQuery.TableSource)new QueryVisitor().Find(sequence.SqlQuery.From, e => { if (e.ElementType == QueryElementType.TableSource) { var t = (SqlQuery.TableSource)e; return t.Source == collectionParent.SqlTable; } return false; }); ts.Joins.Add(join.JoinedTable); } else { sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); } } else { sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable); //collection.SqlQuery = sequence.SqlQuery; } //sql.ParentSql = sequence.SqlQuery; var col = (IParseContext)new SubQueryContext(collection, sequence.SqlQuery, false); return new SelectContext(resultSelector, sequence, col); } } throw new LinqException("Sequence '{0}' cannot be converted to SQL.", expr); }