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