dotnet/efcore · error · InvalidOperationException

The property ' ' on entity type ' ' is not mapped to ' '.

Error message

The property '{property}' on entity type '{entityType}' is not mapped to '{table}'.

What it means

Thrown by FindSharedObjectRootProperty when a property has no column mapping for the given store object (table/view). The method resolves the 'root' property across entities sharing a table, but it cannot proceed if GetColumnName returns null — meaning the property is explicitly excluded or unmapped on that store object. This is an internal API typically invoked during migrations/MigrationsSqlGenerator and annotation resolution, not a query-time check.

Solutions

  1. Inspect the property's mapping with property.GetColumnName(storeObject) before calling FindSharedStoreObjectRootProperty; if null, the property is intentionally unmapped there.
  2. Ensure every entity sharing a table maps all properties referenced by the migration to the same store object.
  3. Remove conflicting HasColumnName overrides or column exclusions for the failing property/table combination.
  4. If you scaffolded the model, regenerate it after aligning the database schema with the model.

Example fix

// before
var root = property.FindSharedStoreObjectRootProperty(storeObject);

// after
if (property.GetColumnName(storeObject) is null)
{
    // property intentionally unmapped on this store object; skip
    return;
}
var root = property.FindSharedStoreObjectRootProperty(storeObject);
Defensive patterns

Strategy: validation

Validate before calling

if (property.GetColumnName(storeObject) is null)
{
    // property is not mapped on this store object; skip root-resolution
    return;
}
var root = property.FindSharedStoreObjectRootProperty(storeObject);

Type guard

static bool IsPropertyMappedToStore(IReadOnlyProperty p, in StoreObjectIdentifier s)
    => !p.DeclaringType.IsMappedToJson() && p.GetColumnName(s) is not null;

Try / catch

try { var root = property.FindSharedStoreObjectRootProperty(storeObject); }
catch (InvalidOperationException ex) when (ex.Message.Contains("is not mapped to"))
{
    // log and skip this property for the store object
}

Prevention

When it happens

Trigger: Calling FindSharedStoreObjectRootProperty(property, storeObject) where the property is not mapped to a column on the specified StoreObjectIdentifier (table, view, function, or SQL query). Happens during migration generation, model differencing, or when a property is explicitly ignored on a table via ToTable(t => t.ExcludeColumnFromMigrations(...)) or IsStored after schema changes.

Common situations: A property was configured with a column name only for a specific table via HasColumnName on a derived store object while the root request targets a different table; using entity splitting or table sharing where one participant omits a column; scaffolding reverse-engineered schemas where columns were dropped; mixing TPT/T phoenix inheritance with column exclusions.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/70d94d73e12c689a. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs:1534

    /// <returns>The property found, or <see langword="null" /> if none was found.</returns>
    public static IProperty? FindSharedStoreObjectRootProperty(
        this IProperty property,
        in StoreObjectIdentifier storeObject)
        => (IProperty?)FindSharedObjectRootProperty(property, storeObject);

    private static IReadOnlyProperty? FindSharedObjectRootProperty(IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
    {
        if (property.DeclaringType.IsMappedToJson())
        {
            //JSON-splitting is not supported
            //Issue #28574
            return null;
        }

        var column = property.GetColumnName(storeObject);
        if (column == null)
        {
            throw new InvalidOperationException(
                RelationalStrings.PropertyNotMappedToTable(
                    property.Name, property.DeclaringType.DisplayName(), storeObject.DisplayName()));
        }

        var rootProperty = property;

        // Limit traversal to avoid getting stuck in a cycle (validation will throw for these later)
        // Using a hashset is detrimental to the perf when there are no cycles
        for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
        {
            var entityType = rootProperty.DeclaringType.ContainingEntityType;
            IReadOnlyProperty? linkedProperty = null;
            foreach (var principalProperty in entityType
                         .FindRowInternalForeignKeys(storeObject)
                         .SelectMany(static fk => fk.PrincipalEntityType.GetProperties()))
            {
                if (principalProperty.GetColumnName(storeObject) == column)
                {

View on GitHub (pinned to 3a2006ef56)