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

Commit 512a5e4

Browse files
committed
Fix Sql Server windowing function when used in Tables with references
1 parent 4adcbdf commit 512a5e4

File tree

3 files changed

+89
-16
lines changed

3 files changed

+89
-16
lines changed

src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.IO;
77
using System.Text;
88
using ServiceStack.Text;
9+
using ServiceStack;
910

1011
namespace ServiceStack.OrmLite.SqlServer
1112
{
@@ -406,11 +407,12 @@ public override string ToSelectStatement(ModelDefinition modelDef,
406407
throw new ApplicationException("Malformed model, no PrimaryKey defined");
407408

408409
orderByExpression = string.Format("ORDER BY {0}",
409-
OrmLiteConfig.DialectProvider.GetQuotedColumnName(modelDef.PrimaryKey.FieldName));
410+
OrmLiteConfig.DialectProvider.GetQuotedColumnName(modelDef, modelDef.PrimaryKey));
410411
}
411412

412413
var ret = string.Format(
413-
"SELECT * FROM (SELECT ROW_NUMBER() OVER ({1}) As RowNum, {0} {2}) AS RowConstrainedResult WHERE RowNum > {3} AND RowNum <= {4}",
414+
"{0} FROM (SELECT ROW_NUMBER() OVER ({2}) As RowNum, {1} {3}) AS RowConstrainedResult WHERE RowNum > {4} AND RowNum <= {5}",
415+
StripTablePrefixes(selectExpression), //SELECT without RowNum to be able to use in SELECT IN () Reference Queries
414416
selectExpression.Substring(selectType.Length),
415417
orderByExpression,
416418
bodyExpression,
@@ -419,5 +421,29 @@ public override string ToSelectStatement(ModelDefinition modelDef,
419421

420422
return ret;
421423
}
424+
425+
string StripTablePrefixes(string selectExpression)
426+
{
427+
if (selectExpression.IndexOf('.') < 0)
428+
return selectExpression;
429+
430+
var sb = new StringBuilder();
431+
var tokens = selectExpression.Split(' ');
432+
foreach (var token in tokens)
433+
{
434+
var parts = token.SplitOnLast('.');
435+
if (parts.Length > 1)
436+
{
437+
sb.Append(" " + parts[parts.Length - 1]);
438+
}
439+
else
440+
{
441+
sb.Append(" " + token);
442+
}
443+
}
444+
445+
return sb.ToString();
446+
}
447+
422448
}
423449
}

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using NUnit.Framework;
66
using ServiceStack.DataAnnotations;
7+
using ServiceStack.OrmLite.Tests.UseCase;
78
using ServiceStack.Text;
89

910
namespace ServiceStack.OrmLite.Tests.Expression
@@ -268,7 +269,47 @@ public void Can_OrderBy_Fields_with_different_sort_directions()
268269
Assert.That(rows.Map(x => x.Letter), Is.EquivalentTo("E,D,D,C,C,C,B,B,A".Split(',')));
269270
Assert.That(rows.Map(x => x.Id), Is.EquivalentTo(Enumerable.Reverse(insertedIds)));
270271
}
272+
}
273+
274+
[Test]
275+
public void Can_select_limit_on_Table_with_References()
276+
{
277+
using (var db = OpenDbConnection())
278+
{
279+
CustomerOrdersUseCase.DropTables(db); //Has conflicting 'Order' table
280+
db.DropAndCreateTable<Order>();
281+
db.DropAndCreateTable<Customer>();
282+
db.DropAndCreateTable<CustomerAddress>();
283+
284+
var customer1 = LoadReferencesTests.GetCustomerWithOrders("1");
285+
db.Save(customer1, references: true);
286+
287+
var customer2 = LoadReferencesTests.GetCustomerWithOrders("2");
288+
db.Save(customer2, references: true);
271289

290+
var results = db.LoadSelect<Customer>(q => q
291+
.OrderBy(x => x.Id)
292+
.Limit(1, 1));
293+
294+
//db.GetLastSql().Print();
295+
296+
Assert.That(results.Count, Is.EqualTo(1));
297+
Assert.That(results[0].Name, Is.EqualTo("Customer 2"));
298+
Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street"));
299+
Assert.That(results[0].Orders.Count, Is.EqualTo(2));
300+
301+
results = db.LoadSelect<Customer>(q => q
302+
.Join<CustomerAddress>()
303+
.OrderBy(x => x.Id)
304+
.Limit(1, 1));
305+
306+
db.GetLastSql().Print();
307+
308+
Assert.That(results.Count, Is.EqualTo(1));
309+
Assert.That(results[0].Name, Is.EqualTo("Customer 2"));
310+
Assert.That(results[0].PrimaryAddress.AddressLine1, Is.EqualTo("2 Humpty Street"));
311+
Assert.That(results[0].Orders.Count, Is.EqualTo(2));
312+
}
272313
}
273314
}
274315
}

tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -337,26 +337,32 @@ public void Can_Save_and_Load_MismatchedAlias_References_using_code_conventions(
337337
}
338338

339339
private Customer AddCustomerWithOrders()
340+
{
341+
var customer = GetCustomerWithOrders();
342+
343+
db.Save(customer, references: true);
344+
345+
return customer;
346+
}
347+
348+
public static Customer GetCustomerWithOrders(string id="1")
340349
{
341350
var customer = new Customer
342351
{
343-
Name = "Customer 1",
352+
Name = "Customer " + id,
344353
PrimaryAddress = new CustomerAddress
345-
{
346-
AddressLine1 = "1 Humpty Street",
347-
City = "Humpty Doo",
348-
State = "Northern Territory",
349-
Country = "Australia"
350-
},
354+
{
355+
AddressLine1 = id + " Humpty Street",
356+
City = "Humpty Doo",
357+
State = "Northern Territory",
358+
Country = "Australia"
359+
},
351360
Orders = new[]
352-
{
353-
new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m},
354-
new Order {LineItem = "Line 2", Qty = 2, Cost = 2.99m},
355-
}.ToList(),
361+
{
362+
new Order {LineItem = "Line 1", Qty = 1, Cost = 1.99m},
363+
new Order {LineItem = "Line 2", Qty = 2, Cost = 2.99m},
364+
}.ToList(),
356365
};
357-
358-
db.Save(customer, references: true);
359-
360366
return customer;
361367
}
362368

0 commit comments

Comments
 (0)