dotnet/efcore · error · InvalidOperationException

' ' is mapped to the view ' ' while ' ' is mapped to the…

Error message

'{entityType}' is mapped to the view '{view}' while '{otherEntityType}' is mapped to the view '{otherView}'. Map all the entity types in the hierarchy to the same view, or remove the discriminator and map them all to different views. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.

What it means

Thrown inside ValidateTphMapping when a derived type resolves to a different View StoreObjectIdentifier than the root. TPH requires all types in the hierarchy to share the same view; mapping a derived type to another view is rejected.

Solutions

  1. Remove the ToView override on the derived type so it uses the root's view.
  2. Switch the hierarchy to TPT/TPC if separate views are intended.
  3. Map the root to the same view as the derived types.

Example fix

// before
modelBuilder.Entity<Person>().ToView("v_People");
modelBuilder.Entity<Customer>().ToView("v_Customers"); // throws 433

// after (separate views -> TPT)
modelBuilder.UseTptMappingStrategy();
modelBuilder.Entity<Person>().ToView("v_People");
modelBuilder.Entity<Customer>().ToView("v_Customers");
Defensive patterns

Strategy: validation

Validate before calling

foreach (var root in modelBuilder.Model.GetEntityTypes().Where(t => t.BaseType == null))
{
    if (root.FindDiscriminatorProperty() == null) continue;
    var rootSo = StoreObjectIdentifier.Create(root, StoreObjectType.View);
    if (rootSo == null) continue;
    foreach (var et in root.GetDerivedTypes())
    {
        var so = StoreObjectIdentifier.Create(et, StoreObjectType.View);
        if (so != null && so.Value != rootSo.Value)
            throw new InvalidOperationException($"{et.DisplayName()} view {so.Value.DisplayName()} differs from root view {rootSo.Value.DisplayName()} (TPH).");
    }
}

Prevention

When it happens

Trigger: A TPH hierarchy where a derived type calls ToView("OtherView") (or is otherwise mapped to a different view than the root).

Common situations: Adding ToView on a derived type under TPH; layered read-model views per type; refactor that diverged view names.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2335

                    {
                        throw new InvalidOperationException(
                            RelationalStrings.StoredProcedureTphDuplicate(
                                entityType.DisplayName(), rootEntityType.DisplayName(), rootId?.DisplayName()));
                    }
                }

                continue;
            }

            switch (storeObjectType)
            {
                case StoreObjectType.Table:
                    throw new InvalidOperationException(
                        RelationalStrings.TphTableMismatch(
                            entityType.DisplayName(), entityId.Value.DisplayName(),
                            rootEntityType.DisplayName(), rootId?.DisplayName()));
                case StoreObjectType.View:
                    throw new InvalidOperationException(
                        RelationalStrings.TphViewMismatch(
                            entityType.DisplayName(), entityId.Value.DisplayName(),
                            rootEntityType.DisplayName(), rootId?.DisplayName()));
                case StoreObjectType.Function:
                    throw new InvalidOperationException(
                        RelationalStrings.TphDbFunctionMismatch(
                            entityType.DisplayName(), entityId.Value.DisplayName(),
                            rootEntityType.DisplayName(), rootId?.DisplayName()));
                case StoreObjectType.InsertStoredProcedure:
                case StoreObjectType.DeleteStoredProcedure:
                case StoreObjectType.UpdateStoredProcedure:
                    throw new InvalidOperationException(
                        RelationalStrings.TphStoredProcedureMismatch(
                            entityType.DisplayName(), entityId.Value.DisplayName(),
                            rootEntityType.DisplayName(), rootId?.DisplayName()));
            }
        }
    }

View on GitHub (pinned to 3a2006ef56)