feat(mapping): collection-mapped properties with multi-result-set read handler - #4
Open
dtraft wants to merge 1 commit into
Open
feat(mapping): collection-mapped properties with multi-result-set read handler#4dtraft wants to merge 1 commit into
dtraft wants to merge 1 commit into
Conversation
This was referenced Sep 8, 2026
Open
…d handler > Claude Code (Claude Fable 5.1) Adds CollectionMapAttributeBase, the write-side hook in Mapper.IterateInMapProperties, and ModelFromReaderWithCollectionsHandler plus MapReaderWithCollectionsAsync overloads, so a model can round-trip a parent row and owned child collections in one query. Collection properties hydrate from subsequent result sets in declaration order; a missing result set throws rather than yielding an empty collection. Models without the attribute keep their existing code paths.
dtraft
force-pushed
the
collection-mapping
branch
from
September 8, 2026 19:04
21f1531 to
a3b3d0a
Compare
dtraft
marked this pull request as ready for review
September 9, 2026 12:50
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.
TL;DR
Adds collection-mapped model properties to the core mapper: a provider-agnostic
CollectionMapAttributeBase, the write-side hook inMapper.IterateInMapProperties, and a new read-side handler that hydrates each collection property from its own result set. Enables a single model (for example Orleans grain state) to round-trip a parent row plus owned child rows in one query.Changes
Mapping/CollectionMapAttributeBase.cs(new): abstract attribute for collection properties; providers supply the structured-parameter expression (ArgentSea.Sql implements it as a table-valued parameter).Mapping/Mapper.cs:IterateInMapPropertiesdetects the attribute and emits the provider's collection-parameter expression (element type resolved forImmutableArray<T>and anyIEnumerable<T>). NewModelFromReaderWithCollectionsHandler<TModel>(aQueryResultModelHandler-compatible method): maps the first result set into the model via the existing single-row path, then for each collection property in declaration order (sorted byMetadataToken) reads the NEXT result set with the existingToList<TElement>row lambdas. A missing result set throwsUnexpectedSqlResultExceptionnaming the model, property and expected position -- a present-but-empty result set yields an empty collection. Hydration delegates are compiled once per model type and cached.Databases.csandShardDataConnection.cs:MapReaderWithCollectionsAsync<TModel>overloads mirroring the existingMapReaderAsyncshapes.Models without the attribute take exactly the existing code paths.
Testing
CollectionMapReadTests/CollectionMapWriteTests(11 tests: one and two collections, declaration order, empty child result set, missing child result set throws, missing record returns null without touchingNextResult, attribute-less model unchanged).ImmutableArray<T>collections, written as TVPs and read back as three result sets against SQL Server.Dependencies
First of a four-PR set: argentsea/shared -> argentsea/sql -> argentsea/Orleans -> argentsea/Orleans.Sql. The other three reference this project and build against these changes.
Related PRs (merge in this order)