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 stored computed column settings ('{value1}' and '{value2}').

What it means

Two properties mapped to the same column specify different IsStored settings for computed columns (one stored physically, the other virtual/computed on read). The physical column can only have one stored-ness, so EF aborts. Thrown from ValidateCompatible via GetIsStored(storeObject).

Source

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

        if (!currentComputedColumnSql.Equals(previousComputedColumnSql, StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateColumnNameComputedSqlMismatch(
                    duplicateProperty.DeclaringType.DisplayName(),
                    duplicateProperty.Name,
                    property.DeclaringType.DisplayName(),
                    property.Name,
                    columnName,
                    storeObject.DisplayName(),
                    previousComputedColumnSql,
                    currentComputedColumnSql));
        }

        var currentStored = property.GetIsStored(storeObject);
        var previousStored = duplicateProperty.GetIsStored(storeObject);
        if (currentStored != previousStored)
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateColumnNameIsStoredMismatch(
                    duplicateProperty.DeclaringType.DisplayName(),
                    duplicateProperty.Name,
                    property.DeclaringType.DisplayName(),
                    property.Name,
                    columnName,
                    storeObject.DisplayName(),
                    previousStored,
                    currentStored));
        }

        var hasDefaultValue = property.TryGetDefaultValue(storeObject, out var currentDefaultValue);
        var duplicateHasDefaultValue = duplicateProperty.TryGetDefaultValue(storeObject, out var previousDefaultValue);
        if ((hasDefaultValue
                || duplicateHasDefaultValue)
            && !Equals(currentDefaultValue, previousDefaultValue))
        {
            currentDefaultValue = GetDefaultColumnValue(property, storeObject);

View on GitHub (pinned to dbf9771522)

Solutions

  1. Set HasComputedColumnSql(sql, stored: x) with the same x value on both properties.
  2. Rename one column via HasColumnName if stored-ness legitimately differs.
  3. Split the conflicting entity into its own table.

Example fix

// before
modelBuilder.Entity<Student>().Property(s => s.Total).HasComputedColumnSql("[A]+[B]", stored: true);
modelBuilder.Entity<Teacher>().Property(t => t.Total).HasComputedColumnSql("[A]+[B]", stored: false);
// after
modelBuilder.Entity<Student>().Property(s => s.Total).HasComputedColumnSql("[A]+[B]", stored: true);
modelBuilder.Entity<Teacher>().Property(t => t.Total).HasComputedColumnSql("[A]+[B]", stored: true);
Defensive patterns

Strategy: validation

Validate before calling

using (var ctx = new MyContext()) { ctx.Model.ToDebugString(); }
var a = ctx.Model.FindEntityType(typeof(Student))!.FindProperty("Total")!.GetIsStored();
var b = ctx.Model.FindEntityType(typeof(Teacher))!.FindProperty("Total")!.GetIsStored();
Debug.Assert(a == b, $"IsStored mismatch: {a} vs {b}");

Try / catch

try { using var ctx = new MyContext(); _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("stored computed column settings"))
{ log.Error("IsStored mismatch on shared computed column: {Msg}", ex.Message); throw; }

Prevention

When it happens

Trigger: Sibling TPH types where one calls HasComputedColumnSql(sql, stored: true) and the other HasComputedColumnSql(sql, stored: false) (or defaults) for the same column; an owned entity and owner disagreeing on stored; table splitting with mismatched stored flags.

Common situations: Tuning a computed column from virtual to persisted on one entity only; cross-provider porting where the default stored-ness changed; copy-paste of config that lost the stored argument on one side.

Related errors


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