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.SelectQuery.Select.IsDistinct && !builder.DataContextInfo.SqlProviderFlags.IsDistinctOrderBySupported) { 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 IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var wrapped = false; if (sequence.SelectQuery.Select.TakeValue != null || sequence.SelectQuery.Select.SkipValue != null) { sequence = new SubQueryContext(sequence); wrapped = true; } var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap(); SqlInfo[] sql; while (true) { var sparent = sequence.Parent; var order = new ExpressionContext(buildInfo.Parent, sequence, lambda); var body = lambda.Body.Unwrap(); sql = builder.ConvertExpressions(order, body, ConvertFlags.Key, null); builder.ReplaceParent(order, sparent); if (wrapped) { break; } // handle situation when order by uses complex field var isComplex = false; foreach (var sqlInfo in sql) { // immutable expressions will be removed later // var isImmutable = QueryHelper.IsConstant(sqlInfo.Sql); if (isImmutable) { continue; } // possible we have to extend this list // isComplex = null != new QueryVisitor().Find(sqlInfo.Sql, e => e.ElementType == QueryElementType.SqlQuery); if (isComplex) { break; } } if (!isComplex) { break; } sequence = new SubQueryContext(sequence); wrapped = true; } if (!methodCall.Method.Name.StartsWith("Then") && !Configuration.Linq.DoNotClearOrderBys) { sequence.SelectQuery.OrderBy.Items.Clear(); } foreach (var expr in sql) { // we do not need sorting by immutable values, like "Some", Func("Some"), "Some1" + "Some2". It does nothing for ordering // if (QueryHelper.IsConstant(expr.Sql)) { continue; } var e = builder.ConvertSearchCondition(expr.Sql); sequence.SelectQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending")); } return(sequence); }