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 data types ('{dataType1}' and '{dataType2}'). What it means
Two properties mapped to the same column specify different store column types via GetColumnType (e.g. 'varchar(50)' vs 'nvarchar(100)'). The validator compares column type strings case-insensitively and aborts if they differ. Thrown from ValidateCompatible.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:1634
}
if (property.IsConcurrencyToken != duplicateProperty.IsConcurrencyToken)
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameConcurrencyTokenMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),
property.Name,
columnName,
storeObject.DisplayName()));
}
var currentTypeString = property.GetColumnType(storeObject);
var previousTypeString = duplicateProperty.GetColumnType(storeObject);
if (!string.Equals(currentTypeString, previousTypeString, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameDataTypeMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),
property.Name,
columnName,
storeObject.DisplayName(),
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 != previousProviderTypeView on GitHub (pinned to dbf9771522)
Solutions
- Set HasColumnType to the identical string on both properties (case-insensitive match is required).
- If the types genuinely differ, rename one column with HasColumnName.
- Remove the explicit HasColumnType so both inherit the provider default for the CLR type.
Example fix
// before
modelBuilder.Entity<Student>().Property(s => s.Code).HasColumnType("varchar(20)");
modelBuilder.Entity<Teacher>().Property(t => t.Code).HasColumnType("nvarchar(20)");
// after
modelBuilder.Entity<Student>().Property(s => s.Code).HasColumnType("varchar(20)");
modelBuilder.Entity<Teacher>().Property(t => t.Code).HasColumnType("varchar(20)"); Defensive patterns
Strategy: validation
Validate before calling
using (var ctx = new MyContext()) { ctx.Model.ToDebugString(); }
var a = ctx.Model.FindEntityType(typeof(Student))!.FindProperty("Code")!.GetColumnType();
var b = ctx.Model.FindEntityType(typeof(Teacher))!.FindProperty("Code")!.GetColumnType();
Debug.Assert(string.Equals(a, b, StringComparison.OrdinalIgnoreCase), $"ColumnType mismatch: {a} vs {b}"); Try / catch
try { using var ctx = new MyContext(); _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("different data types"))
{ log.Error("Column-type mismatch on shared column: {Msg}", ex.Message); throw; } Prevention
- Avoid explicit HasColumnType on shared columns; let the provider derive the type from the CLR type and facets.
- If explicit types are required, store them in constants shared by all configurations of that column.
- Add a startup model-build test asserting column-type parity.
When it happens
Trigger: Sibling TPH types calling HasColumnType("varchar(50)") and HasColumnType("nvarchar(100)") on a same-named property; an owned entity and owner setting explicit types that don't match; table splitting where one side forces a custom column type.
Common situations: One team uses a custom column type for a Code property (e.g. 'citext') while another uses plain text; refactoring a property to a domain-specific type without updating siblings; mixing [Column(TypeName=...)] annotations with Fluent HasColumnType on different entities.
Related errors
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/2debae21de32fdbf.
Report an issue: GitHub.