Skip to content

Docs: state the NULL policy and the async transaction token correctly; fix the struct constructor sentence - #137

Merged
electricessence merged 4 commits into
masterfrom
docs/null-policy-and-transaction-token
Nov 15, 2026
Merged

electricessence merged 4 commits into
masterfrom
docs/null-policy-and-transaction-token

Conversation

@electricessence

Copy link
Copy Markdown
Collaborator

States the NULL policy and the async transaction token behaviour correctly, and fixes a wrong sentence about a struct's own parameterless constructor, so newcomers read facts that match the code.

What changed

  • NULL policy: the full rules live in mapping.md "NULL in a non-nullable column"; the table row, the matching and required bullets, the single-value bullet and the Dapper comparison now link to it instead of restating it. It gains the single-value case: Map<int>().Single() over a NULL is 0, Map<int?>() and Map<string>() give null. coming-from-dapper.md says Dapper's QuerySingle<int> over a NULL throws. That page's link also pointed to "Types and NULL" (a section about value conversion that says nothing about NULL); it now points to "NULL in a non-nullable column".
  • Async transaction token: foundation.md "Transactions" says the token is checked after the action returns (a cancelled token throws and nothing commits) and the commit is sent without the token. New async sample transaction_async.
  • Struct constructor: mapping.md said a struct's own public parameterless constructor is not called; it is (new T()). The sentence is fixed, and the test AStructWithAPublicParameterlessConstructor_IsBuiltWithIt now asserts a side effect only the constructor can produce, not only Id == 7.
  • Constructor rule, two lines: a record with a second public constructor is in the "two or more public constructors" row (unless the second is parameterless); an all-optional constructor does not count as parameterless.
  • Excluding a member: one line saying new(nameof(X.Member), null) needs no null!.
  • Not changed: whats-new-11.md (the release PR writes the notes), the three pages on reading output values back, anything under Source/.

Verification

  • Samples (new checks in Program.cs; check-only models in ConstructorRules.cs; a commit-token recorder in Transactions.cs): dotnet run --project docsite/samples -c Release ends with All 125 sample checks passed.
  • Checks added: single-value NULL (int 0, int? and string null); Dapper QuerySingle<int> over NULL throws; the exclusion pair leaves the member unmapped while a column of that name exists and the others map; a record with a second constructor and an all-optional constructor are rejected; a record with a parameterless second constructor uses it; the async transaction commits; a token cancelled in the action throws OperationCanceledException and rolls back; the commit receives a token that cannot be cancelled although a live token was passed.
  • The struct claim is asserted by the Core test, run with dotnet test Tests/Open.Database.Extensions.Core.Tests -c Release --filter UnmappableTypeTests: 213 passed on net10.0 and on net11.0.
  • DocFX build: Build succeeded, 0 warnings, 0 errors. quick-check.ps1: Release build 0 warnings, 0 errors, format style and analyzers clean.

Not done / decisions

  • The "A missing column and a NULL" table in mapping.md and the existing NULL text in whats-new-11.md still restate parts of the NULL rule; left alone on purpose (a different cut of the rule, and the release PR owns the notes).
  • The "Dapper throws" claim is checked against Dapper 2.1.89 on SQLite only.
  • The commit-token claim is shown with a recording transaction wrapper, since SQLite cannot observe the token itself.

🤖 Generated with Claude Code

electricessence and others added 4 commits November 14, 2026 15:24
…ructor, constructor rules, excluding a member

State the NULL policy once (mapping.md, "NULL in a non-nullable column") and point the other pages at it, including the single-value case (Map<int>().Single() over NULL is 0; Dapper's QuerySingle<int> throws). State that the async transaction helpers check the token after the action and send the commit without it. Correct the sentence that said a struct's own parameterless constructor is not called (it is), and the test that claimed the same. Add two lines to the constructor rule (a record with a second public constructor; an all-optional constructor is not parameterless) and one to the exclusion recipe (new(nameof(X.Member), null) needs no null!). Every new claim has a sample check.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s it)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@electricessence
electricessence merged commit 44059a5 into master Nov 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant