Skip to content

Navigation Menu

Sign in
Sign up

feat(mapping): MapToSqlTableValuedParameter attribute and empty/struct TVP fixes - #2

Draft
dtraft wants to merge 1 commit into
master from
collection-mapping
Draft

feat(mapping): MapToSqlTableValuedParameter attribute and empty/struct TVP fixes #2
dtraft wants to merge 1 commit into
master from
collection-mapping

Conversation

@dtraft

@dtraft dtraft commented Sep 8, 2026
edited
Loading

Copy link
Copy Markdown

Posted by: Claude Code (Claude Fable 5.1) | 2026年09月08日

TL;DR

Adds MapToSqlTableValuedParameterAttribute so a collection property maps to a SQL Server table-valued parameter on write (and, with the shared mapper change, to an additional result set on read), and fixes two TVP edge cases in AddSqlTableValuedParameter.

Changes

  • SqlMapAttributes.cs: new MapToSqlTableValuedParameterAttribute(parameterName, typeName) : CollectionMapAttributeBase. The emitted expression calls AddSqlTableValuedParameter<TElement> and sets SqlParameter.TypeName. Value-type collections (ImmutableArray<T>) are explicitly converted to IEnumerable<T> (Expression.Call requires reference-assignability), and a default (uninitialized) ImmutableArray<T> -- which throws on enumeration -- is normalized to Empty.
  • SqlParameterCollectionExtensions.cs: both AddSqlTableValuedParameter overloads send DBNull.Value for an empty collection (an empty IEnumerable<SqlDataRecord> cannot supply TDS metadata and is rejected by the driver; SQL Server treats a null TVP as an empty table). The columnList overload previously had no empty guard at all.
  • Tests (new): test/CollectionMapWriteTests.cs (populated/empty/default collections through both overloads and through CreateInputParameters, for List<T> and ImmutableArray<T>) and test/CollectionMapReadTests.cs (multi-result-set hydration, declaration order, empty vs missing result set, missing record, attribute-less model, ImmutableArray<T> read).

Testing

ArgentSea.Sql.Test: 116 passed, 0 failed (101 pre-existing + 15 new). Exercised live against SQL Server by a downstream Orleans grain whose state carries two TVP-mapped collections.

Dependencies

Depends on argentsea/shared (CollectionMapAttributeBase and the read-side handler). Second of four: shared -> sql -> Orleans -> Orleans.Sql.

Related PRs (merge in this order)

  1. feat(mapping): collection-mapped properties with multi-result-set read handler shared#4
  2. feat(mapping): MapToSqlTableValuedParameter attribute and empty/struct TVP fixes #2
  3. feat(persistence): hydrate CollectionMap grain-state properties from extra result sets Orleans#5
  4. fix(persistence): resolve named OrleansDbPersistenceOptions in the Db storage factory Orleans.Sql#3

...t TVP fixes
> Claude Code (Claude Fable 5.1)
Adds MapToSqlTableValuedParameterAttribute mapping a collection property to a table-valued parameter, converting value-type collections such as ImmutableArray<T> to IEnumerable<T> explicitly and normalizing a default ImmutableArray<T> to Empty. Both AddSqlTableValuedParameter overloads now send DBNull for an empty collection instead of an unusable empty record list. Adds read and write tests for the collection mapping.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /