dotnet/efcore · error · InvalidOperationException

The view '{view}' cannot be used for entity type '{entityTyp

Error message

The view '{view}' cannot be used for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and there is no relationship between their primary keys.

What it means

The view-sharing analog of error 430. Two or more entity types mapped to the same view must be connected by inheritance or a PK-to-PK foreign key. The validator at line 1358-1365 throws IncompatibleViewNoRelationship when it encounters a second 'root' view-mapped type with no connecting relationship to the first.

Source

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

                if (mappedType.BaseType != null)
                {
                    var principalType = mappedType.FindForeignKeys(mappedType.FindPrimaryKey()!.Properties)
                        .First(fk => fk.PrincipalKey.IsPrimaryKey()
                            && unvalidatedTypes.Contains(fk.PrincipalEntityType))
                        .PrincipalEntityType;
                    throw new InvalidOperationException(
                        RelationalStrings.IncompatibleViewDerivedRelationship(
                            storeObject.DisplayName(),
                            mappedType.DisplayName(),
                            principalType.DisplayName()));
                }

                continue;
            }

            if (root != null)
            {
                throw new InvalidOperationException(
                    RelationalStrings.IncompatibleViewNoRelationship(
                        storeObject.DisplayName(),
                        mappedType.DisplayName(),
                        root.DisplayName()));
            }

            root = mappedType;
        }

        Check.DebugAssert(root != null);
        unvalidatedTypes.Remove(root);
        var typesToValidate = new Queue<IEntityType>();
        typesToValidate.Enqueue(root);

        while (typesToValidate.Count > 0)
        {
            var entityType = typesToValidate.Dequeue();
            var typesToValidateLeft = typesToValidate.Count;

View on GitHub (pinned to dbf9771522)

Solutions

  1. Define a foreign key between the primary keys of the two view-mapped entity types.
  2. Model one entity as owned by the other (.OwnsOne) so EF creates the implicit relationship.
  3. Map the unrelated entity to its own view or to a table.

Example fix

// before
modelBuilder.Entity<OrderSummary>().ToView("v_Orders");
modelBuilder.Entity<OrderStats>().ToView("v_Orders"); // no FK

// after
modelBuilder.Entity<OrderStats>()
    .HasOne<OrderSummary>()
    .WithOne()
    .HasForeignKey<OrderStats>(s => s.Id);
modelBuilder.Entity<OrderSummary>().ToView("v_Orders");
modelBuilder.Entity<OrderStats>().ToView("v_Orders");
Defensive patterns

Strategy: validation

Validate before calling

var byView = modelBuilder.Model.GetEntityTypes()
    .Where(e => !e.IsMappedToJson() && e.GetViewName() is not null)
    .GroupBy(e => (e.GetViewName(), e.GetViewSchema()))
    .Where(g => g.Count() > 1);
foreach (var grp in byView)
{
    var types = grp.ToList();
    for (int i = 1; i < types.Count; i++)
    {
        bool connected = types[i].BaseType != null && types.Contains(types[i].BaseType)
            || HasIdentifyingFk(types[i], types[0])
            || HasIdentifyingFk(types[0], types[i]);
        if (!connected)
            throw new InvalidOperationException(
                $"View '{grp.Key.Item1}' shared by {types[0].Name} and {types[i].Name} without a linking FK.");
    }
}
bool HasIdentifyingFk(IEntityType dep, IEntityType prin)
    => dep.FindPrimaryKey() is { } pk
       && dep.FindForeignKeys(pk.Properties).Any(fk =>
            fk.PrincipalKey.IsPrimaryKey() && fk.PrincipalEntityType == prin);

Prevention

When it happens

Trigger: Calling `.ToView("SameView")` on two unrelated entity types without a foreign key between their primary keys. Detected during the initial root-finding loop in ValidateSharedViewCompatibility.

Common situations: Backing two read-only query entities by the same database view without defining the relationship; renaming views to collide; keyless entities mapped to a shared view without an ownership link.

Related errors


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