Opt out of Default Sort (by Id)
See original GitHub issueDESCRIPTION
I have a scenario in which I do NOT want a default sort by Id to be applied. Is there a way to turn off default sorting or intervene at a seam.
STEPS TO REPRODUCE
I have the following classes:
FundList
- contains many Funds
- which has a fundcategory
- which also contains many FundData (but will always only display one which is enforced with filter)
I want to display a table as such: (where Fund & FundCategory fields are being displayed with FundData fields per row)
Consider the following query:
/api/v1/fundlists?include=funds,funds.category,funds.fundData&fields=id,name&fields[funds]=id,name,ticker&fields[funds.category]=name&fields[funds.fundData]=ttlGPA,prosNetExp,ret3Mo,ret1Yr,ret3Yr,ret5Yr,ret10Yr&filter[funds.fundData]=and(equals(periodYear,'2020'),equals(periodQuarter,'2'))&sort[funds.fundData]=-ttlGPA
I need to offer sorting on FundData columns, such as GPA and ExpRatio, but since a default sort of Fund.Id is being performed, it’s taking precedence over the FundData sorts.
SELECT [t].[Id], [t].[Name], [t1].[Id], [t1].[Name], [t1].[Ticker], [t1].[c], [t1].[Name0], [t1].[Id0], [t1].[Id1], [t1].[TtlGPA],
[t1].[ProsNetExp], [t1].[Ret3Mo], [t1].[Ret1Yr], [t1].[Ret3Yr], [t1].[Ret5Yr], [t1].[Ret10Yr],[t1].[Id2]
FROM (
SELECT TOP(2) [f].[Id], [f].[Name]
FROM [FundLists] AS [f]
ORDER BY [f].[Id]
) AS [t]
LEFT JOIN (
SELECT [f1].[Id], [f1].[Name], [f1].[Ticker], CASE
WHEN [f2].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [c], [f2].[Name] AS [Name0], [f2].[Id] AS [Id0], [f0].[Id] AS [Id1], [t0].[TtlGPA], [t0].[ProsNetExp], [t0].[Ret3Mo],
[t0].[Ret1Yr], [t0].[Ret3Yr], [t0].[Ret5Yr], [t0].[Ret10Yr], [t0].[Id] AS [Id2], [f0].[FundListId]
FROM [FundListFunds] AS [f0]
INNER JOIN [Funds] AS [f1] ON [f0].[FundId] = [f1].[Id]
LEFT JOIN [FundCategories] AS [f2] ON [f1].[CategoryId] = [f2].[Id]
LEFT JOIN (
SELECT [f3].[TtlGPA], [f3].[ProsNetExp], [f3].[Ret3Mo], [f3].[Ret1Yr], [f3].[Ret3Yr], [f3].[Ret5Yr], [f3].[Ret10Yr],
[f3].[Id], [f3].[FundId]
FROM [FundData] AS [f3]
WHERE ([f3].[PeriodYear] = 2020) AND ([f3].[PeriodQuarter] = 2)
) AS [t0] ON [f1].[Id] = [t0].[FundId]
) AS [t1] ON [t].[Id] = [t1].[FundListId]
ORDER BY [t].[Id], [t1].[Id], [t1].[Id1], [t1].[TtlGPA] DESC, [t1].[Id2]
EXPECTED BEHAVIOR
Returned records to be sorted by the field indicated in querystring.
ACTUAL BEHAVIOR
It’s being ordered as a tertiary column instead.
VERSIONS USED
- JsonApiDotNetCore version: master branch as of 11/15/2020
- ASP.NET Core version: 3.1
- Entity Framework Core version: 3.1.10
- Database provider: SQL Server
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
Agreed! Since I can’t get a proper server-side sort on child object fields (which I’d need for paging) via JADNC, what I’ve ended up doing is flattening the data into a database view, creating a resource class against that view so it’s fully sortable, filterable, etc. Not my first choice to be creating “view models” - would much rather have the hierarchical/relational data to serve, but time constraints are real at this point, so just need to get this out. It’s just for a single, very specific, read-only scenario. For all other CRUD operations, just following the usual route with relational data.
Thanks, I think I understand your use case now. And it sounds like a legitimate reason for us to provide an option to disable default sorting by ID. However, I wonder if such an option would actually solve your use case. Let me explain.
When sending
GET /api/v1/fundlists?include=funds&sort=name
, we generate a LINQ query along the lines of:And when sending
GET /api/v1/fundlists?include=funds&sort[funds]=name
, we generate:Assuming we provide an option to disable automatic sort by ID and it is activated, the line with comment is omitted in the last example. With that change, the query means:
What you actually need, I believe, is a way to set top-level sorting based on a condition of a child table, such as:
which is not something we have syntax for to express in a query string or resource definition. Instead you could accomplish this by overriding
EntityFrameworkCoreRepository.GetAll
, where you can add custom C# expressions to theIQueryable
that is being sent to EF Core.In case I misunderstand, it helps if you can provide the LINQ query you expect JADNC to produce.