Repository navigation
Expose the projection, and project get only mapped properties - #1439
Merged
Merged
Conversation
IEfGraphQLService gains ApplyProjection, which narrows a query to what the request selected under the field being resolved, the way the query fields do. A resolver that builds a query of its own, such as a mutation reading back the entity it returns, had no way to do this, and built Include chains by hand: every column of every included entity, and one include per selected navigation. A mapped property with no setter, such as a database computed column, is now bound through the field EF writes it through. A select cannot assign a property with no setter, so selecting one used to give up on the select and load the whole entity, and everything under it, through includes. An expression bodied property has no field and no column, so it still does. Breaking: * IEfGraphQLService<TDbContext> has a new member, so an implementation of it other than the library's no longer compiles. * A query that selects a mapped get only property is now projected. A resolver reading a property of its source that it has not declared used to work in such a query, since the whole entity was loaded. It now reads a default, as it already did in any other query. Bump version to 36.0.0
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.
Breaking changes
IEfGraphQLService<TDbContext>has a new member,ApplyProjection. An implementation of the interface other than the library's no longer compiles. Code that only calls the interface is unaffected.WithProjectionor a projection-based resolve.ApplyProjectionThe query fields apply the select projection themselves. A resolver that builds a query of its own had no way to, so a mutation reading back the entity it returns had to build
Includechains by hand from the selection:That loads every column of every included entity, applies the arguments of navigation fields in memory, and gives the resolvers of the returned entity a different entity to the one a query gives them.
ApplyProjectionnarrows the query to what the request selected under the field being resolved: the select a query field would build, or includes where the entity cannot be projected.Get-only mapped properties
A select cannot assign a property with no setter, so selecting one gave up on the select and loaded the whole entity, and everything under it, through includes.
LastModified { get; }as a computed column is a common case, and selecting it turned any query into a whole-entity load.A property with no setter that is mapped in the model is now bound through the field Entity Framework writes it through:
An expression-bodied property has no field and no column, so selecting one still falls back, as does a get-only property that is not mapped.
Tests
Custom_mutation_reads_back_with_projection: a mutation with its own resolver reads its entity back throughApplyProjection, with a select and the children'sorderByapplied by the database.Query_database_computed_column_readonly_property,Single_query_with_collection_navigation_to_readonly_entityand the twoConnection_with_read_only_property_*tests now show a select in place of the whole entity.Readonly_root_with_navigation_falls_back_to_includeandCollection_navigation_to_entity_with_readonly_property_falls_back_to_full_includeselect an expression-bodied property instead of the computed column, so they still cover the fallback they are named for.Docs
docs/defining-graphs.mdgains sections on read-only properties, abstract types and applying the projection to a custom query, and "When Projections Are Not Used" is rewritten: it said read-only properties and abstract types always bypass the projection.