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
- Resolve the design-time model: dbContext.GetService<IDesignTimeModel>().Model and read GetComment() from its entity types.
- 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
- Never read GetComment from dbContext.Model at runtime; use IDesignTimeModel.
- Build a helper that always routes design-time metadata reads through IDesignTimeModel.
- Tag runtime-vs-design-time metadata accessors in your codebase to prevent misuse.
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
- The requested configuration is not stored in the read-optimi
- The requested configuration is not stored in the read-optimi
- The requested configuration is not stored in the read-optimi
- The requested configuration is not stored in the read-optimi
- 'Except' cannot be called on the builder returned by 'HasAut
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/85a406c62b9688af.
Report an issue: GitHub.