Add JSON column support for default ordering - #113
Merged
Conversation
OrderBy/ThenBy now accept a property path, so a property of a ToJson()
mapped column can be used for default ordering. EF Core translates the
path to a read of the JSON document:
builder.Entity<Order>()
.OrderByDescending(_ => _.Metadata.Priority);
ORDER BY CAST(JSON_VALUE([o].[Metadata], '$.Priority') AS int) DESC
Paths of any depth work, and JSON properties mix with ordinary columns in
the same chain. Cross context conflict detection, inherited ordering, and
redundant ordering detection all understand the dotted path.
Index creation is skipped for an ordering that reaches into JSON, since a
JSON property is not a column of the entity's table. This follows the
existing string column behaviour: the index is skipped, the ordering
still applies.
JSON mapped collections are left in document order. EF Core throws on an
ordered Include over one in a tracking query, so ordering them would
break queries that work today.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OrderBy/ThenBynow accept a property path, so a property of aToJson()mapped column can be used for default ordering.EF Core translates the path to a read of the JSON document:
Paths of any depth work (
_ => _.Info.Audit.Modifiedbecomes'$.Audit.Modified'), and JSON properties mix with ordinary columns in the same chain. Everything else composes as before: the ordering is applied beforeSkip/Take/First, explicit ordering in a query still takes precedence, and inheritance, cross context conflict detection and redundant ordering detection all understand the dotted path.Implementation
PropertyPathresolves a member chain rooted at the lambda parameter.OrderByClausewalks that chain instead of building a singleExpression.Property.ClauseMetadatastores the dotted path, so derived type replay, conflict detection across contexts andRedundantOrderkeep working unchanged.Two deliberate limits
Indexes are skipped for JSON paths. A JSON property is not a column of the entity's table, so there is nothing to name in
HasIndex. This follows the existing string column behaviour: the index is skipped, the ordering still applies. A composite ordering is skipped whole when any one of its clauses reaches into JSON.JSON collections keep document order.
Include(_ => _.Tags.OrderBy(...))over aToJson()collection throwsInvalidOperationExceptionon a tracking query; it only works underAsNoTracking. Auto applying ordering there would break queries that work today, soIncludeOrderingApplicatornow leaves JSON mapped collections alone. Without that guard, a CLR type used both as a regular entity and as a JSON collection elsewhere would hit exactly that failure.Tests
Ten tests in
JsonColumnTests.cscover ordering, nesting, mixed chains,Take, index skipping, redundancy detection,requireOrderingForAllEntitiesagainst JSON owned types, and that a trackedIncludeover a JSON collection still works. Three Verify snapshots lock in the generated SQL.Full suite passes in Release (139 tests), verified against SQL Server via LocalDb.