dotnet/efcore · critical · InvalidOperationException

Model building is not supported when publishing with NativeA

Error message

Model building is not supported when publishing with NativeAOT. Use a compiled model.

What it means

Thrown when EF Core lazily resolves the relational type mapping for a runtime DbFunction parameter (RuntimeDbFunctionParameter.TypeMapping) under NativeAOT, where dynamic code is unsupported. Like the DbFunction return mapping, parameter mapping resolution requires the runtime type-mapping source and cannot run under AOT without a compiled model.

Source

Thrown at src/EFCore.Relational/Metadata/RuntimeDbFunctionParameter.cs:73

    }

    /// <summary>
    ///     Gets the function to which this parameter belongs.
    /// </summary>
    public virtual RuntimeDbFunction Function { get; }

    /// <summary>
    ///     Gets or sets the type mapping for this parameter.
    /// </summary>
    /// <returns>The type mapping.</returns>
    public virtual RelationalTypeMapping? TypeMapping
    {
        get => NonCapturingLazyInitializer.EnsureInitialized(
            ref _typeMapping, this, static parameter =>
            {
                if (!RuntimeFeature.IsDynamicCodeSupported)
                {
                    throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel);
                }

                var relationalTypeMappingSource =
                    (IRelationalTypeMappingSource)((IModel)parameter.Function.Model).GetModelDependencies().TypeMappingSource;
                return relationalTypeMappingSource.FindMapping(parameter._storeType)!;
            });

        set => _typeMapping = value;
    }

    /// <summary>
    ///     Returns a string that represents the current object.
    /// </summary>
    /// <returns>A string that represents the current object.</returns>
    public override string ToString()
        => ((IDbFunctionParameter)this).ToDebugString(MetadataDebugStringOptions.SingleLineDefault);

    /// <summary>

View on GitHub (pinned to dbf9771522)

Solutions

  1. Generate a compiled model via `dotnet ef dbcontext optimize` and register it with `UseCompiledModel`.
  2. Re-run the optimizer whenever DbFunction signatures (parameters) change.
  3. Drop `<PublishAot>` if you cannot use a compiled model.
  4. Validate the compiled model is active at startup (assert `RuntimeFeature.IsDynamicCodeSupported` or that the compiled model type is registered).

Example fix

// before
options.UseSqlServer(cs);
// after
dotnet ef dbcontext optimize
options.UseSqlServer(cs).UseCompiledModel(typeof(MyCompiledModel).Assembly);
Defensive patterns

Strategy: validation

Validate before calling

if (!System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported
    && options.FindExtension<CoreOptionsExtension>()?.CompiledModel is null)
{
    throw new InvalidOperationException("DbFunction parameter type mapping requires a compiled model under NativeAOT.");
}

Prevention

When it happens

Trigger: Querying through a mapped DbFunction that takes parameters, in an app published with `<PublishAot>true</PublishAot>` and no compiled model; reading `.TypeMapping` on a parameter when `RuntimeFeature.IsDynamicCodeSupported` is false.

Common situations: AOT-published app that uses parameterized DbFunctions; missing or stale compiled model after adding parameters to a DbFunction; works in dev (JIT) but throws on `dotnet publish` AOT.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/2037dabc7601d28d. Report an issue: GitHub.