diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 815b7646..85835297 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -693,6 +693,7 @@ namespace FreeSql.Tests.Sqlite .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => new { a.Key.tt2, a.Key.mod4 }) .OrderByDescending(a => a.Count()) .Offset(10) .Limit(2) @@ -804,7 +805,17 @@ namespace FreeSql.Tests.Sqlite [Fact] public void OrderBy() { - var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + var sql = select.OrderBy(a => new Random().NextDouble()).ToSql(); + + sql = select.OrderBy(a => a.Id).OrderBy(a => a.Title).OrderByDescending(a => a.CreateTime).ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""Clicks"", a.""TypeGuid"", a.""Title"", a.""CreateTime"" +FROM ""tb_topic22"" a +ORDER BY a.""Id"", a.""Title"", a.""CreateTime"" DESC", sql); + + sql = select.OrderBy(a => new { a.Id, a.Title }).OrderByDescending(a => a.CreateTime).ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""Clicks"", a.""TypeGuid"", a.""Title"", a.""CreateTime"" +FROM ""tb_topic22"" a +ORDER BY a.""Id"", a.""Title"", a.""CreateTime"" DESC", sql); } [Fact] public void OrderByRandom() diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index bdc0e758..06c59d5c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -760,8 +760,32 @@ namespace FreeSql.Internal.CommonProvider _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereGlobalFilter); return this as TSelect; } - protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); - protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); + protected TSelect InternalOrderBy(Expression column) + { + if (column.NodeType == ExpressionType.Lambda) column = (column as LambdaExpression)?.Body; + switch (column?.NodeType) + { + case ExpressionType.New: + var newExp = column as NewExpression; + if (newExp == null) break; + for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], true, null)); + return this as TSelect; + } + return this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)); + } + protected TSelect InternalOrderByDescending(Expression column) + { + if (column.NodeType == ExpressionType.Lambda) column = (column as LambdaExpression)?.Body; + switch (column?.NodeType) + { + case ExpressionType.New: + var newExp = column as NewExpression; + if (newExp == null) break; + for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], true, null)} DESC"); + return this as TSelect; + } + return this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC"); + } public List InternalToList(Expression select) => this.ToListMapReader(this.GetExpressionField(select)); protected string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 68ca4c50..757aaff1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -96,6 +96,15 @@ namespace FreeSql.Internal.CommonProvider } public void InternalOrderBy(Expression exp, bool isDescending) { + if (exp.NodeType == ExpressionType.Lambda) exp = (exp as LambdaExpression)?.Body; + if (exp?.NodeType == ExpressionType.New) + { + var newExp = exp as NewExpression; + if (newExp != null) + for (var a = 0; a < newExp.Members.Count; a++) + InternalOrderBy(newExp.Arguments[a], isDescending); + return; + } var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null });