Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit ce79733

Browse files
committed
Add support for inverting sort direction of orderBy with '=' prefix e.g. orderBy=Id,-Name
1 parent c99b5ca commit ce79733

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,20 @@ private SqlExpression<T> OrderByFields(string orderBySuffix, FieldDefinition[] f
305305
return this;
306306
}
307307

308+
static class OrderBySuffix
309+
{
310+
public const string Asc = "";
311+
public const string Desc = " DESC";
312+
}
313+
308314
public virtual SqlExpression<T> OrderByFields(params FieldDefinition[] fields)
309315
{
310-
return OrderByFields("", fields);
316+
return OrderByFields(OrderBySuffix.Asc, fields);
311317
}
312318

313319
public virtual SqlExpression<T> OrderByFieldsDescending(params FieldDefinition[] fields)
314320
{
315-
return OrderByFields(" DESC", fields);
321+
return OrderByFields(OrderBySuffix.Desc, fields);
316322
}
317323

318324
private SqlExpression<T> OrderByFields(string orderBySuffix, string[] fieldNames)
@@ -322,15 +328,21 @@ private SqlExpression<T> OrderByFields(string orderBySuffix, string[] fieldNames
322328
var sbOrderBy = new StringBuilder();
323329
foreach (var fieldName in fieldNames)
324330
{
325-
var field = FirstMatchingField(fieldName);
331+
var reverse = fieldName.StartsWith("-");
332+
var useSuffix = reverse
333+
? (orderBySuffix == OrderBySuffix.Asc ? OrderBySuffix.Desc : OrderBySuffix.Asc)
334+
: orderBySuffix;
335+
var useName = reverse ? fieldName.Substring(1) : fieldName;
336+
337+
var field = FirstMatchingField(useName);
326338
if (field == null)
327-
throw new ArgumentException("Could not find field " + fieldName);
339+
throw new ArgumentException("Could not find field " + useName);
328340
var qualifiedName = DialectProvider.GetQuotedColumnName(field.Item1, field.Item2);
329341

330342
if (sbOrderBy.Length > 0)
331343
sbOrderBy.Append(", ");
332344

333-
sbOrderBy.Append(qualifiedName + orderBySuffix);
345+
sbOrderBy.Append(qualifiedName + useSuffix);
334346
}
335347

336348
this.orderBy = sbOrderBy.Length == 0

tests/ServiceStack.OrmLite.Tests/Expression/SqlExpressionTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,33 @@ public void Can_do_ToCountStatement_with_SqlExpression_if_where_expression_refer
241241
db.Exists<LetterFrequency>(q => q.Join<LetterStat>().Where<LetterStat>(x => x.Id > 0)));
242242
}
243243
}
244+
245+
[Test]
246+
public void Can_OrderBy_Fields_with_different_sort_directions()
247+
{
248+
using (var db = OpenDbConnection())
249+
{
250+
db.DropAndCreateTable<LetterFrequency>();
251+
db.DropAndCreateTable<LetterStat>();
252+
253+
var i = 0;
254+
"A,B,B,C,C,C,D,D,E".Split(',').Each(letter => {
255+
db.Insert(new LetterFrequency { Letter = letter }, selectIdentity: true);
256+
});
257+
258+
var rows = db.Select<LetterFrequency>(q => q.OrderByFields("Letter", "Id"));
259+
Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("A,B,B,C,C,C,D,D,E".Split(',')));
260+
Assert.That(rows.Map(x => x.Id), Is.EquivalentTo("1,2,3,4,5,6,7,8,9".Split(',').Map(int.Parse)));
261+
262+
rows = db.Select<LetterFrequency>(q => q.OrderByFields("Letter", "-Id"));
263+
Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("A,B,B,C,C,C,D,D,E".Split(',')));
264+
Assert.That(rows.Map(x => x.Id), Is.EquivalentTo("1,3,2,6,5,4,8,7,9".Split(',').Map(int.Parse)));
265+
266+
rows = db.Select<LetterFrequency>(q => q.OrderByFieldsDescending("Letter", "-Id"));
267+
Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("E,D,D,C,C,C,B,B,A".Split(',')));
268+
Assert.That(rows.Map(x => x.Id), Is.EquivalentTo("9,7,8,4,5,6,2,3,1".Split(',').Map(int.Parse)));
269+
}
270+
271+
}
244272
}
245273
}

0 commit comments

Comments
 (0)