dotnet/efcore · error · InvalidOperationException
' . ' and ' . ' are both mapped to column ' ' in ' ', but…
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 have different explicit column types via GetColumnType (e.g. 'date' vs 'datetime', or 'bigint' vs 'int'). Because one physical column can only have one type, EF rejects the model rather than silently coercing. The comparison is case-insensitive.
Solutions
- Call HasColumnType("<same-type>") on both properties.
- Drop the explicit HasColumnType from one side so it derives from the type mapping and matches.
- Verify the two properties' ClrType are compatible and align the column type accordingly.
- If types really must differ, remap one property to a distinct column.
Example fix
// before
modelBuilder.Entity<Event>().Property(e => e.Occurred).HasColumnType("datetime");
modelBuilder.Entity<EventAudit>().Property(a => a.Occurred).HasColumnType("datetime2"); // shared
// after
modelBuilder.Entity<Event>().Property(e => e.Occurred).HasColumnType("datetime2");
modelBuilder.Entity<EventAudit>().Property(a => a.Occurred).HasColumnType("datetime2"); Defensive patterns
Strategy: validation
Validate before calling
foreach (var (col, props) in sharedColumnGroups)
{
var types = props.Select(p => p.GetColumnType(storeObject)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
if (types.Count > 1)
Console.WriteLine($"Column {col} has conflicting column types: {string.Join(", ", types)}");
} Try / catch
try { _ = db.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("different data types")) { // align HasColumnType on both properties } Prevention
- Set HasColumnType explicitly on shared columns to remove ambiguity.
- Prefer relying on CLR type + convention over manual HasColumnType where possible.
- Smoke-test the model at startup.
When it happens
Trigger: ValidateCompatible() reads property.GetColumnType(storeObject) and duplicateProperty.GetColumnType(storeObject), and string.Equals(..., OrdinalIgnoreCase) returns false. Common when both sides call HasColumnType with different literals.
Common situations: Scaffolding a legacy schema where two entities overlapped on a column; mixed annotations vs fluent HasColumnType; an owned type's column type set explicitly while the owner uses the convention-driven type.
Related errors
- ' . ' and ' . ' are both mapped to column ' ' in ' ', but…
- ' . ' and ' . ' are both mapped to column ' ' in ' ', but…
- ' . ' and ' . ' are both mapped to column ' ' in ' ', but…
- ' . ' and ' . ' are both mapped to column ' ' in ' ', but…
- ' . ' and ' . ' are both mapped to column ' ' in ' ', but…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/2debae21de32fdbf.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)