dotnet/efcore · error · InvalidOperationException

The requested configuration is not stored in the read-optimi

Error message

The requested configuration is not stored in the read-optimized model, please use 'DbContext.GetService<IDesignTimeModel>().Model'.

What it means

IEntityType.GetComment() reads a design-time-only annotation (RelationalAnnotationNames.Comment) that is stripped from the read-optimized runtime model. When the instance is a RuntimeEntityType, EF throws CoreStrings.RuntimeModelMissingData (RelationalEntityTypeExtensions.cs:966). Use the design-time model to read table comments.

Source

Thrown at src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs:966

    ///     It is useful when iterating over all entity types to avoid processing the same check constraint more than once.
    ///     Use <see cref="GetCheckConstraints(IEntityType)" /> to also return check constraints declared on base types.
    /// </remarks>
    /// <param name="entityType">The entity type to get the check constraints for.</param>
    public static IEnumerable<ICheckConstraint> GetDeclaredCheckConstraints(this IEntityType entityType)
        => CheckConstraint.GetDeclaredCheckConstraints(entityType).Cast<ICheckConstraint>();

    #endregion Check constraint

    #region Comment

    /// <summary>
    ///     Returns the comment for the table this entity is mapped to.
    /// </summary>
    /// <param name="entityType">The entity type.</param>
    /// <returns>The comment for the table this entity is mapped to.</returns>
    public static string? GetComment(this IReadOnlyEntityType entityType)
        => (entityType is RuntimeEntityType)
            ? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData)
            : (string?)entityType[RelationalAnnotationNames.Comment];

    /// <summary>
    ///     Configures a comment to be applied to the table this entity is mapped to.
    /// </summary>
    /// <param name="entityType">The entity type.</param>
    /// <param name="comment">The comment for the table this entity is mapped to.</param>
    public static void SetComment(this IMutableEntityType entityType, string? comment)
        => entityType.SetOrRemoveAnnotation(RelationalAnnotationNames.Comment, comment);

    /// <summary>
    ///     Configures a comment to be applied to the table this entity is mapped to.
    /// </summary>
    /// <param name="entityType">The entity type.</param>
    /// <param name="comment">The comment for the table.</param>
    /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
    /// <returns>The configured comment.</returns>
    public static string? SetComment(

View on GitHub (pinned to dbf9771522)

Solutions

  1. Resolve the design-time model: dbContext.GetService<IDesignTimeModel>().Model and read GetComment() from its entity types.
  2. Restrict these metadata reads to design time (migrations, scaffolding) rather than runtime application code.

Example fix

// before
var comment = dbContext.Model.GetEntityTypes()
    .First().GetComment();   // throws: runtime model

// after
var designModel = dbContext.GetService<IDesignTimeModel>().Model;
var comment = designModel.GetEntityTypes()
    .First().GetComment();
Defensive patterns

Strategy: validation

Validate before calling

// Resolve design-time model before reading design-time-only metadata.
var model = dbContext.GetService<IDesignTimeModel>().Model;
foreach (var et in model.GetEntityTypes())
{
    var comment = et.GetComment(); // safe
}

Type guard

static bool IsDesignTime(IEntityType et) => et is not RuntimeEntityType;

Prevention

When it happens

Trigger: Calling entityType.GetComment() where entityType was obtained from DbContext.Model (the runtime IModel) instead of from the design-time model.

Common situations: Writing a migration/annotation tool, a code generator, or a test that reads comments from context.Model.GetEntityTypes() at runtime; mixing design-time metadata accessors with runtime model traversal.

Related errors


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