dotnet/efcore · error · InvalidOperationException
The view ' ' cannot be used for entity type ' ' since it is…
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
View-mapping analog of error 393/397. Thrown by ValidateSharedViewCompatibility when two or more entity types share a view but there is no PK-to-PK FK between them and no inheritance relationship. The message lists the view, the unlinked entity type, and the root (first type to claim the view).
Solutions
- If the entities really represent different rows of the same view, add a 1:1 PK FK: builder.Entity<B>().HasOne<A>().WithOne().HasForeignKey<B>(b => b.Id).
- Map one of them to a different view, or replace ToView with ToTable if writes are intended.
- Use keyless entities (HasNoKey) and ToView for genuine query-only types so they do not collide on the PK-share path.
Example fix
// before
builder.Entity<Customer>().ToView("CustomerView");
builder.Entity<Order>().ToView("CustomerView"); // unlinked
// after
builder.Entity<Order>(b =>
{
b.ToView("CustomerView");
b.HasOne<Customer>().WithOne().HasForeignKey<Order>(o => o.CustomerId);
}); Defensive patterns
Strategy: validation
Validate before calling
var byView = model.GetEntityTypes().Where(e => e.GetViewName() != null).GroupBy(e => e.GetViewName());
foreach (var grp in byView)
{
var list = grp.ToList();
for (int i = 1; i < list.Count; i++)
{
var et = list[i];
bool linked = et.BaseType != null && list.Any(t => t.IsAssignableFrom(et))
|| et.FindForeignKeys(et.FindPrimaryKey()?.Properties ?? new List<Microsoft.EntityFrameworkCore.Metadata.IProperty>())
.Any(fk => list.Contains(fk.PrincipalEntityType) && fk.PrincipalKey.IsPrimaryKey());
if (!linked)
Console.WriteLine($"{et.Name} shares view '{grp.Key}' with {list[0].Name} but has no link.");
}
} Prevention
- Use ToView for query-only keyless entities to avoid the PK-share path entirely.
- If two writable types must share a view, configure a 1:1 PK FK between them.
- Code-review all ToView calls to catch accidental collisions.
When it happens
Trigger: builder.Entity<A>().ToView("V") and builder.Entity<B>().ToView("V") with no HasOne/WithOne PK FK between them and no inheritance link. ValidateSharedViewCompatibility finds root != null when processing the second type and throws.
Common situations: Read-only reporting views shared by multiple entity types without an explicit 1:1 relationship; refactor that renamed a view and caused a collision; using ToView for the wrong purpose (should be a query root, not a table-share).
Related errors
- Both ' ' and ' ' are mapped to the view ' '. All the entity…
- ' ' is mapped to the view ' ' while ' ' is mapped to the…
- The view ' ' cannot be used for entity type ' ' since it is…
- A rows affected parameter, result column or return value…
- An Azure Cosmos DB container name is defined on entity type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/7abeaf5793ba16a9.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)