{"record":{"id":"87568747cece950e","repo":"dotnet/efcore","slug":"entity-type-entitytype-doesn-t-contain-a-prope","errorCode":null,"errorMessage":"Entity type '{entityType}' doesn't contain a property mapped to the store-generated concurrency token column '{missingColumn}' which is used by another entity type sharing the table '{table}'. Add a store-generated property to '{entityType}' which is mapped to the same column; it may be in shadow state.","messagePattern":"Entity type '(.+?)' doesn't contain a property mapped to the store-generated concurrency token column '(.+?)' which is used by another entity type sharing the table '(.+?)'\\. Add a store-generated property to '(.+?)' which is mapped to the same column; it may be in shadow state\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":1455,"sourceCode":"            if (missingConcurrencyTokens != null)\n            {\n                missingConcurrencyTokens.Clear();\n                foreach (var (concurrencyColumn, concurrencyProperties) in concurrencyColumns!)\n                {\n                    if (TableSharingConcurrencyTokenConvention.IsConcurrencyTokenMissing(concurrencyProperties, entityType, mappedTypes))\n                    {\n                        missingConcurrencyTokens.Add(concurrencyColumn);\n                    }\n                }\n            }\n\n            ValidateCompatible(entityType, storeObject, propertyMappings, missingConcurrencyTokens, logger);\n\n            if (missingConcurrencyTokens != null)\n            {\n                foreach (var concurrencyColumn in missingConcurrencyTokens)\n                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.MissingConcurrencyColumn(\n                            entityType.DisplayName(), concurrencyColumn, storeObject.DisplayName()));\n                }\n            }\n        }\n\n        var columnOrders = new Dictionary<int, List<string>>();\n        foreach (var property in propertyMappings.Values)\n        {\n            var columnOrder = property.GetColumnOrder(storeObject);\n            if (!columnOrder.HasValue)\n            {\n                continue;\n            }\n\n            var columns = columnOrders.GetOrAddNew(columnOrder.Value);\n            columns.Add(property.GetColumnName(storeObject)!);\n        }","sourceCodeStart":1437,"sourceCodeEnd":1473,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L1437-L1473","documentation":"Thrown during shared-table column validation when entity types share a table and one of them declares a store-generated concurrency token (e.g. rowversion/xmin), but another entity type sharing that same table has no property mapped to that concurrency-token column. EF requires every type sharing the table to observe the token so optimistic-concurrency checks stay consistent across the shared row.","triggerScenarios":"Table splitting (owned types or one-to-one PK sharing) where the principal has IsRowToken()/IsConcurrencyToken() but the dependent sharing the table has no matching property. TableSharingConcurrencyTokenConvention.IsConcurrencyTokenMissing returns true for that entity, the column is added to missingConcurrencyTokens, and the validator throws.","commonSituations":"Adding a [Timestamp]/byte[] RowVersion to a principal entity that is table-split with an owned/detail entity; switching a column to a concurrency token after the split was configured; using PostgreSQL xmin without exposing it on all split partners.","solutions":["Add a shadow or explicit concurrency-token property on the entity type named in the message, mapped to the same column (e.g. .Property<byte[]>(\"RowVersion\").IsRowToken().HasColumnName(<column>)).","Remove the concurrency token from the other entity if all partners do not need it.","Stop table-sharing (map the dependent to its own table) so the token only lives on the principal."],"exampleFix":"// before\nmodelBuilder.Entity<Order>().ToTable(\"Orders\");\nmodelBuilder.Entity<OrderDetails>().ToTable(\"Orders\");\nmodelBuilder.Entity<Order>().Property<byte[]>(\"RowVersion\").IsRowToken();\n// OrderDetails has no RowVersion -> error\n\n// after - add a shadow concurrency token mapped to the same column\nmodelBuilder.Entity<OrderDetails>()\n    .Property<byte[]>(\"RowVersion\")\n    .IsRowToken()\n    .HasColumnName(\"RowVersion\");","handlingStrategy":"validation","validationCode":"// Detect table-split types missing the shared concurrency token column before validation.\nvar tokenProps = sharedTypes.SelectMany(t => t.GetProperties())\n    .Where(p => p.IsConcurrencyToken()).Select(p => p.GetColumnName(storeObject)).ToHashSet();\nforeach (var t in sharedTypes)\n{\n    var myTokenCols = t.GetProperties().Where(p => p.IsConcurrencyToken()).Select(p => p.GetColumnName(storeObject)).ToHashSet();\n    foreach (var missing in tokenProps.Except(myTokenCols))\n        Console.WriteLine($\"{t.Name} missing concurrency column {missing}\");\n}","typeGuard":null,"tryCatchPattern":"try { _ = db.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains(\"doesn't contain a property mapped to the store-generated concurrency token column\")) { // add the shadow token property in OnModelCreating }","preventionTips":["When adding IsRowToken()/IsConcurrencyToken() to a principal, audit every entity type that shares its table.","Prefer exposing the concurrency token as a shadow property on all split partners.","Add a startup model-build smoke test to surface sharing errors before runtime."],"tags":["model-validation","concurrency-token","table-splitting","relational"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}