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); }
static void ParseSkip(ExpressionParser parser, IParseContext sequence, ISqlExpression prevSkipValue, ISqlExpression expr) { var sql = sequence.SqlQuery; parser.SqlProvider.SqlQuery = sql; sql.Select.Skip(expr); parser.SqlProvider.SqlQuery = sql; if (sql.Select.TakeValue != null) { if (parser.SqlProvider.IsSkipSupported || !parser.SqlProvider.IsTakeSupported) sql.Select.Take(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.TakeValue, "-", sql.Select.SkipValue, Precedence.Additive))); if (prevSkipValue != null) sql.Select.Skip(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), prevSkipValue, "+", sql.Select.SkipValue, Precedence.Additive))); } if (!parser.SqlProvider.TakeAcceptsParameter) { var p = sql.Select.SkipValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
protected override bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return methodCall.IsQueryable("SelectMany") && methodCall.Arguments.Count == 3 && ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Parameters.Count == 1; }
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; }
static void ParseTake(ExpressionParser parser, IParseContext sequence, ISqlExpression expr) { var sql = sequence.SqlQuery; parser.SqlProvider.SqlQuery = sql; sql.Select.Take(expr); if (sql.Select.SkipValue != null && parser.SqlProvider.IsTakeSupported && !parser.SqlProvider.IsSkipSupported) { if (sql.Select.SkipValue is SqlParameter && sql.Select.TakeValue is SqlValue) { var skip = (SqlParameter)sql.Select.SkipValue; var parm = (SqlParameter)sql.Select.SkipValue.Clone(new Dictionary<ICloneableElement,ICloneableElement>(), _ => true); parm.SetTakeConverter((int)((SqlValue)sql.Select.TakeValue).Value); sql.Select.Take(parm); var ep = (from pm in parser.CurrentSqlParameters where pm.SqlParameter == skip select pm).First(); ep = new ParameterAccessor { Expression = ep.Expression, Accessor = ep.Accessor, SqlParameter = parm }; parser.CurrentSqlParameters.Add(ep); } else sql.Select.Take(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.SkipValue, "+", sql.Select.TakeValue, Precedence.Additive))); } if (!parser.SqlProvider.TakeAcceptsParameter) { var p = sql.Select.TakeValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
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 bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { if (!methodCall.IsQueryable("Join", "GroupJoin") || methodCall.Arguments.Count != 5) return false; var body = ((LambdaExpression)methodCall.Arguments[2].Unwrap()).Body.Unwrap(); if (body.NodeType == ExpressionType .MemberInit) { var mi = (MemberInitExpression)body; bool throwExpr; if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0) throwExpr = true; else throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment); if (throwExpr) throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in join is not allowed.", body.Type)); } return true; }
protected override bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return methodCall.IsQueryable("Skip", "Take"); }
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 bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return(methodCall.IsQueryable("Average", "Min", "Max", "Sum")); }
protected abstract IParseContext ParseMethodCall(ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery);
public bool CanParse(ExpressionParser parser, Expression expression, SqlQuery sqlQuery) { return(Parse(parser, expression, sqlQuery, (n, _) => n > 0)); }
public bool CanParse(ExpressionParser parser, Expression expression, SqlQuery sqlQuery) { if (expression.NodeType == ExpressionType.Call) return CanParseMethodCall(parser, (MethodCallExpression)expression, sqlQuery); return false; }
protected override bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return(methodCall.IsQueryable("Where")); }
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) { return(parser.ParseSequence(parent, methodCall.Arguments[0], sqlQuery)); }
public IParseContext ParseSequence(ExpressionParser parser, IParseContext parent, Expression expression, SqlQuery sqlQuery) { return(new ScalarSelectContext { Parser = parser, Parent = parent, Expression = expression, SqlQuery = sqlQuery }); }
public bool CanParse(ExpressionParser parser, Expression expression, SqlQuery sqlQuery) { return(expression.NodeType == ExpressionType.Lambda && ((LambdaExpression)expression).Parameters.Count == 0); }
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); }
public IParseContext ParseSequence(ExpressionParser parser, IParseContext parent, Expression expression, SqlQuery sqlQuery) { if (expression.NodeType == ExpressionType.Call) return ParseMethodCall(parser, parent, (MethodCallExpression)expression, sqlQuery); return null; }
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 TableContext(ExpressionParser parser, SqlQuery sqlQuery) { Parser = parser; SqlQuery = sqlQuery; }
protected override bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return methodCall.IsQueryable("DefaultIfEmpty"); }
protected abstract bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery);
protected override bool CanParseMethodCall(ExpressionParser parser, MethodCallExpression methodCall, SqlQuery sqlQuery) { return(methodCall.IsQueryable("First", "FirstOrDefault", "Single", "SingleOrDefault")); }
protected abstract IParseContext ParseMethodCall (ExpressionParser parser, IParseContext parent, MethodCallExpression methodCall, SqlQuery sqlQuery);