Skip to content

11.0.0-preview.1: retarget main to net11.0 / EF Core 11 / Npgsql 11 after the v10.0.0 tag, with the four behaviour changes as named tests #103

Closed

Description

@CaffeinatedCoder

Scope since 2026-10-18: this is 11.0.0-preview.1, the retarget itself, under the 11.0.0 epic #147.

Raising the runtime floor of the released 10.x line is not on the table: 10.x stays on .NET 10 for its whole life.

Two couplings found on 2026-10-18 after #158/#159:


The four measured behaviour changes (original analysis, 2026-10-17)

EF Core 11 (11.0.0-rc.2.26504.105), .NET 11 RC2 and the Npgsql EF provider 11.0.0-rc.1.1 are published; EF 11 needs the .NET 11 runtime, so the move is a retarget, not a bump. A source diff of dotnet/efcore release/10.0 (a5e42cd) against release/11.0 (c8a9187, 2026-10-16) on the query and storage paths shows every interface this package implements unchanged: IRelationalParameterBasedSqlProcessorFactory, RelationalParameterBasedSqlProcessor.Process(Expression, ParametersCacheDecorator), IRelationalTypeMappingSourcePlugin, IMethodCallTranslatorPlugin, IMemberTranslatorPlugin, IAggregateMethodCallTranslatorPlugin, IQueryExpressionInterceptor, RelationalTypeMapping.Clone. The two EF1001 usages (PgBinaryExpression in ValueSetSqlGuard, PgNewArrayExpression in ValueSetsMethodCallTranslator) are Npgsql-internal, and the Npgsql 11 provider's notes list no query-tree changes; the NodaTime satellite's EF1001 pragmas are only the analyzer reading this package's own .Internal namespace.

Four things do change under the package and need a measured answer before 10.x targets EF 11 (none is a compile error):

  1. JsonValueReaderWriter<T>.ToJson throws ArgumentNullException on null unless the new virtual HandlesNullWrites returns true. LiteralJsonValueReaderWriter<T> and the three YearMonth* writers override only ToJsonTyped. Whether EF 11 reaches ToJson with null for a nullable range or set property inside a ToJson() complex type (the "null and empty, kept apart" row in docs/efcore.md) must be tested; if it does, HandlesNullWrites and a null branch are the fix.
  2. RuntimeConstantExpression (experimental, precompiled queries) is a new node that reduces to a ConstantExpression. RangeVariantConstantRetyper in ValueRangesQueryExpressionInterceptor relies on EF inlining Constant(value, Int32Range.Finite) and overrides VisitConstant. Whether the new node can carry a variant-typed range past the retyper is the one item that could change an answer; InlineRangeConstantTests and the integration suite decide it.
  3. SqlExpressionFactory simplifies a == b ? null : a to NULLIF(a, b). ValueSetSqlGuard judges the final tree; a NULLIF over an array_cat-derived value is a new shape it has no arm for and must refuse (equality) rather than pass. Seed it.
  4. Npgsql EF 11 raises the default PostgreSQL compatibility target from 14 to 16. Nothing this package emits is version-gated today; confirm timerange and multirange SQL are unaffected.

Also noted: EF 11 removes ITypeMappingSource.FindMapping(MemberInfo) and CoreTypeMapping.ValueGeneratorFactory (not used here), adds RelationalTypeMapping.GetDefaultProviderValue() (not overridden here; check whether the range and set mappings should), and Property(…) no longer configures primitive collections (value sets are not IEnumerable<T>, so inert). Npgsql 11 core is not on NuGet yet; its range, multirange, array and infinity behaviour is unverified.

Proposed: a CI job (allowed to fail until GA) that builds the four packages and runs the EF translation and integration suites against EF 11 RC + Npgsql EF 11 RC on net11.0, with the four items above as named tests; then the retarget PR for 10.x, with docs/migration.md saying what the consumer must do.

Sources: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-11.0/breaking-changes ; https://www.npgsql.org/efcore/release-notes/11.0.html ; https://npgsql.org/doc/release-notes/11.0.html ; https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-11/overview

Found by the platform-horizon review, 2026-10-17.

Activity

  1. added
    choreBuild, CI, packaging, refactoring with no behaviour change
    package/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQL
    package/efcore-nodatimeAffects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime
    on Oct 17, 2026
  2. added this to the 11.0.0 milestone on Oct 18, 2026
  3. CaffeinatedCoder commented on Oct 18, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Scope widened 2026-10-18, now under the 11.0.0 epic #147.

    This issue is 11.0.0-preview.1: the retarget itself, not only the measurement.

    • Branch net11 on top of main, carrying only: net11.0 in the four csproj files, EF 11 RC2 and Npgsql EF 11 RC references, #if around the two EF1001 usages if their shapes moved, PostgreSQL floor 16 in the docs. It merges main forward after every 10.0.0 fix; it never receives a fix first.
    • Public API identical to 10.0.0; the ApiCompat baseline is 10.0.0 and the pack must be clean.
    • The four behaviour changes above become named tests, run in the integration suite against PostgreSQL 16 and 18.
    • The release workflow publishes 11.0.0-preview.1 from the branch (prerelease path, --latest=false); one preview per .NET 11 RC while the line is open.
    • The consumer smoke test runs with the .NET 11 SDK, including the NativeAOT consumer.
  4. changed the title [-]Prepare 10.x for EF Core 11 / Npgsql 11 / .NET 11: measure the four behaviour changes under the plugin[/-] [+]11.0.0-preview.1: retarget to net11.0 / EF Core 11 / Npgsql 11 on the net11 branch, with the four behaviour changes as named tests[/+] on Oct 18, 2026
  5. CaffeinatedCoder commented on Oct 18, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Measured in ComplexIndexes' retarget (its draft PR #47, 2026-10-18): Npgsql.EntityFrameworkCore.PostgreSQL 11.0.0-rc.1.1 pins Microsoft.EntityFrameworkCore.Relational exactly, so a net11 branch that references it sits on EF Core 11 RC1, not RC2, until Npgsql publishes an RC2 build. Reference the EF packages at the version Npgsql pins rather than fighting NU1107. Also: package validation cannot compare a net11.0 asset against a net10.0 baseline (ComplexIndexes #46, the twin of #157), so the ApiCompat gate on net11 needs PackageValidationBaselineFrameworkReferences or an explicit statement that the 11 line's first comparable baseline is 11.0.0 itself.

  6. changed the title [-]11.0.0-preview.1: retarget to net11.0 / EF Core 11 / Npgsql 11 on the net11 branch, with the four behaviour changes as named tests[/-] [+]11.0.0-preview.1: retarget main to net11.0 / EF Core 11 / Npgsql 11 after the v10.0.0 tag, with the four behaviour changes as named tests[/+] on Oct 19, 2026
  7. CaffeinatedCoder commented on Oct 19, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Retarget done on main for 11.0.0-preview.1 (PR to follow). What the four measured items turned out to be, each now a named test in EfCore11RetargetTests (integration, runs on 16 and 18) and the two translation-level ones in EfCore11ShapeTests:

    1. HandlesNullWrites — EF Core 11 writes a null property as JSON null without calling the plugin's writers (all report HandlesNullWrites == false); the document holds "MaybeTags": null and reads back as null, for the complex and the owned path. No change needed.
    2. RuntimeConstantExpression — created in shaper processing and precompiled-query generation, after translation; the interceptor runs at QueryCompilationStarting, so the inlined variant constant still arrives as a ConstantExpression and the retyper handles it. No change needed.
    3. NULLIF — EF Core 11 does write a == b ? null : a as NULLIF(a, b). The guard's CASE arm no longer saw the equality; a NULLIF arm refuses it as equality (proved by revert: without it the refusal was the generic "This use of it").
    4. Compatibility target 16 — Npgsql 11 defaults to 16; the timerange and multirange SQL is byte-identical under SetPostgresVersion(14) and runs on the live server.

    Core TFM decision: net11.0 on all four packages, one TFM per line, recorded in the changelog's platform line.

    Package validation: as predicted, a net11.0 asset cannot be paired with the net10.0 baseline (PKV006, no member comparison). Directory.Build.props ignores the baseline's framework with the statement, and a dotnet apicompat run over the four 10.0.0 assemblies against this build reports no breaking changes; the mechanical gate returns when 11.0.0 is the baseline (CONTRIBUTING says so).

    ComplexIndexes: no 11 preview on NuGet (5.4.1 still pins [10.0.0, 11.0.0), its #38 open), so ComplexIndexesCrossTests and the fourth smoke consumer are conditioned on net10.0 as described here; CaffeinatedCoder/EFCore.ComplexIndexes#42 turns them back on.

    Not predicted, found by the first test run (each its own issue, fixed in the same PR): #286 (.NET 11 reads hour 24), #287 (EF Core 11 rewrites RangeSet.Contains, with #288 for the 10.x line), #289 (jsonb_set_lax), #290 (empty captured collection as a bare NULL), #291 (Native AOT trap in the set types' default IFormattable.ToString under ILCompiler 11 RC2).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/releaseVersioning, changelogs, release wiringchoreBuild, CI, packaging, refactoring with no behaviour changepackage/efcoreAffects CodoMetis.ValueRanges.EFCore.PostgreSQLpackage/efcore-nodatimeAffects CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions