dotnet/efcore · error · InvalidOperationException
Entity type ' ' has a split mapping for ' ' that is shared…
Error message
Entity type '{entityType}' has a split mapping for '{storeObject}' that is shared with the entity type '{principalEntityType}', but the main mappings of these types do not share a table. Map the split fragments of '{entityType}' to non-shared tables or map the main fragment to '{principalStoreObject}'. What it means
Thrown in the entity-splitting validator when a split fragment of an entity shares its table with a principal entity (via a row internal foreign key, i.e. table splitting between two entities), but the main mappings of those two entities do not themselves share a table. The split fragment's principal main store object (StoreObjectIdentifier.Create of the principal for the same store-object type) differs from the dependent's mainStoreObject, so the relationship is inconsistent.
Solutions
- Align the principal's main mapping to the dependent's main table so the split fragment is shared consistently: ToTable the principal to the same store object.
- Or map the dependent's split fragments to non-shared tables (remove the row-internal-FK sharing on that fragment).
- Make the ownership/table-splitting consistent across both the main and split mappings.
Example fix
// before
modelBuilder.Entity<Customer>().ToTable("Customers");
modelBuilder.Entity<Customer>()
.OwnsOne(c => c.Audit, a => a.ToTable("Customers")) // shares via row IFK
.SplitToTable("CustomerExtras", t => t.Property(c => c.Notes));
// but principal main table differs -> throws 439
// after - keep principal main table aligned
modelBuilder.Entity<Customer>().ToTable("Customers");
modelBuilder.Entity<Customer>().OwnsOne(c => c.Audit, a => a.ToTable("Customers"));
// do not split a fragment that shares a table unless main tables also share Defensive patterns
Strategy: validation
Validate before calling
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var fragments = EntityTypeMappingFragment.Get(entityType);
if (fragments == null) continue;
foreach (var fragment in fragments)
{
var main = StoreObjectIdentifier.Create(entityType, fragment.StoreObject.StoreObjectType);
if (main == null) continue;
foreach (var fk in entityType.FindRowInternalForeignKeys(fragment.StoreObject))
{
var principalMain = StoreObjectIdentifier.Create(fk.PrincipalEntityType, fragment.StoreObject.StoreObjectType);
if (principalMain != null && principalMain.Value != main.Value)
throw new InvalidOperationException($"{entityType.DisplayName()} split fragment {fragment.StoreObject.DisplayName()} shares a table with {fk.PrincipalEntityType.DisplayName()} but main mappings differ ({main.Value.DisplayName()} vs {principalMain.Value.DisplayName()}).");
}
}
} Prevention
- When using SplitToTable together with owned/table-split types, keep the principal's main table aligned with the dependent's main table.
- After changing a principal's ToTable, audit dependent split fragments for consistency.
- Add a model test that validates split fragments against row-internal-FK principals.
When it happens
Trigger: An entity Customer is table-split with AuditInfo (AuditInfo has a row internal FK to Customer on the split fragment), but AuditInfo's main ToTable points somewhere different than Customer's main table, so the principalMainFragment != mainStoreObject for the fragment.
Common situations: Mixing entity splitting (SplitToTable) with owned/table-split types whose main tables drift apart; refactor that changed a principal's main table without updating the dependent's split fragment; inconsistent ToTable across an ownership.
Related errors
- The entity type ' ' is mapped to ' '. However the principal…
- Entity type ' ' has a split mapping for ' ', but it also…
- Entity type ' ' has a split mapping for ' ', but it doesn't…
- The entity type ' ' is mapped to ' '. However one of its…
- The entity type ' ' is not mapped, so by default the owned…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/0655c094be404b1c.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2407
throw new InvalidOperationException(
RelationalStrings.EntitySplittingUnmappedMainFragment(
entityType.DisplayName(), fragment.StoreObject.DisplayName(), fragment.StoreObject.StoreObjectType));
}
if (fragment.StoreObject == mainStoreObject)
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingConflictingMainFragment(
entityType.DisplayName(), fragment.StoreObject.DisplayName()));
}
foreach (var foreignKey in entityType.FindRowInternalForeignKeys(fragment.StoreObject))
{
var principalMainFragment = StoreObjectIdentifier.Create(
foreignKey.PrincipalEntityType, fragment.StoreObject.StoreObjectType)!.Value;
if (principalMainFragment != mainStoreObject)
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingUnmatchedMainTableSplitting(
entityType.DisplayName(),
fragment.StoreObject.DisplayName(),
foreignKey.PrincipalEntityType.DisplayName(),
principalMainFragment.DisplayName()));
}
}
var propertiesFound = false;
foreach (var property in entityType.GetProperties())
{
var columnName = property.GetColumnName(fragment.StoreObject);
if (columnName == null)
{
if (property.IsPrimaryKey())
{
throw new InvalidOperationException(
RelationalStrings.EntitySplittingMissingPrimaryKey(View on GitHub (pinned to 3a2006ef56)