dotnet/efcore · error · InvalidOperationException

'{entityType1}.{property1}' and '{entityType2}.{property2}'

Error message

'{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but are configured to use different provider types ('{type1}' and '{type2}').

What it means

Two properties mapped to the same column have different provider CLR types after value-converter resolution, and at least one of them participates in a key, foreign key, or unique index. EF Core requires the underlying provider type to match for relational constraints to work. Thrown from ValidateCompatible.

Source

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

                    previousTypeString,
                    currentTypeString));
        }

        var typeMapping = property.GetRelationalTypeMapping();
        var duplicateTypeMapping = duplicateProperty.GetRelationalTypeMapping();
        var currentProviderType = typeMapping.Converter?.ProviderClrType.UnwrapNullableType()
            ?? typeMapping.ClrType;
        var previousProviderType = duplicateTypeMapping.Converter?.ProviderClrType.UnwrapNullableType()
            ?? duplicateTypeMapping.ClrType;
        if (currentProviderType != previousProviderType
            && (property.IsKey()
                || duplicateProperty.IsKey()
                || property.IsForeignKey()
                || duplicateProperty.IsForeignKey()
                || (property.IsIndex() && property.GetContainingIndexes().Any(i => i.IsUnique))
                || (duplicateProperty.IsIndex() && duplicateProperty.GetContainingIndexes().Any(i => i.IsUnique))))
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateColumnNameProviderTypeMismatch(
                    duplicateProperty.DeclaringType.DisplayName(),
                    duplicateProperty.Name,
                    property.DeclaringType.DisplayName(),
                    property.Name,
                    columnName,
                    storeObject.DisplayName(),
                    previousProviderType.ShortDisplayName(),
                    currentProviderType.ShortDisplayName()));
        }

        var currentComputedColumnSql = property.GetComputedColumnSql(storeObject) ?? "";
        var previousComputedColumnSql = duplicateProperty.GetComputedColumnSql(storeObject) ?? "";
        if (!currentComputedColumnSql.Equals(previousComputedColumnSql, StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateColumnNameComputedSqlMismatch(
                    duplicateProperty.DeclaringType.DisplayName(),

View on GitHub (pinned to dbf9771522)

Solutions

  1. Make the value converter (or absence thereof) identical on both properties so the provider CLR type matches.
  2. Rename one property's column with HasColumnName so they no longer share.
  3. Move one entity to its own table via ToTable to decouple the key/FK columns.

Example fix

// before
modelBuilder.Entity<Student>().Property(s => s.Id).HasConversion<StronglyTypedIdConverter>();   // provider: Guid
modelBuilder.Entity<Teacher>().Property(t => t.Id);                                   // provider: int
// after (same provider type on shared key column)
modelBuilder.Entity<Student>().Property(s => s.Id).HasConversion<StronglyTypedIdConverter>();
modelBuilder.Entity<Teacher>().Property(t => t.Id).HasConversion<StronglyTypedIdConverter>();
Defensive patterns

Strategy: validation

Validate before calling

using (var ctx = new MyContext()) { ctx.Model.ToDebugString(); }
// Inspect the value converter provider types of key/FK properties sharing a column.
static Type? providerType(IProperty p) => p.FindRelationalTypeMapping()?.Converter?.ProviderClrType.UnwrapNullableType() ?? p.ClrType;
var a = providerType(ctx.Model.FindEntityType(typeof(Student))!.FindProperty("Id")!);
var b = providerType(ctx.Model.FindEntityType(typeof(Teacher))!.FindProperty("Id")!);
Debug.Assert(a == b, $"Provider type mismatch: {a} vs {b}");

Try / catch

try { using var ctx = new MyContext(); _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("different provider types"))
{ log.Error("Provider-type mismatch on shared key/FK column: {Msg}", ex.Message); throw; }

Prevention

When it happens

Trigger: A same-named key/FK property on sibling TPH types where one uses a value converter producing int and the other produces Guid or string; a shared key column where one side has ValueConverter<T,Guid> and the other has ValueConverter<T,int>; table splitting where a unique-indexed column differs in provider type.

Common situations: Switching a strongly-typed ID from one value-converter backing store to another on only one entity; adding a value converter to one sibling's key without applying it to the FK mirror; refactoring key types in part of the hierarchy.

Related errors


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