{"record":{"id":"c07753aefc514926","repo":"dotnet/efcore","slug":"the-indexes-index1-on-entitytype1-and-index-c07753","errorCode":null,"errorMessage":"The indexes {index1} on '{entityType1}' and {index2} on '{entityType2}' are both mapped to '{table}.{indexName}', but with different sort orders.","messagePattern":"The indexes (.+?) on '(.+?)' and (.+?) on '(.+?)' are both mapped to '(.+?)\\.(.+?)', but with different sort orders\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs","lineNumber":99,"sourceCode":"        }\n\n        return index.IsUnique != duplicateIndex.IsUnique\n            ? shouldThrow\n                ? throw new InvalidOperationException(\n                    RelationalStrings.DuplicateIndexUniquenessMismatch(\n                        index.DisplayName(),\n                        index.DeclaringEntityType.DisplayName(),\n                        duplicateIndex.DisplayName(),\n                        duplicateIndex.DeclaringEntityType.DisplayName(),\n                        index.DeclaringEntityType.GetSchemaQualifiedTableName(),\n                        index.GetDatabaseName(storeObject)))\n                : false\n            : (index.IsDescending is null) != (duplicateIndex.IsDescending is null)\n            || (index.IsDescending is not null\n                && duplicateIndex.IsDescending is not null\n                && !index.IsDescending.SequenceEqual(duplicateIndex.IsDescending))\n                ? shouldThrow\n                    ? throw new InvalidOperationException(\n                        RelationalStrings.DuplicateIndexSortOrdersMismatch(\n                            index.DisplayName(),\n                            index.DeclaringEntityType.DisplayName(),\n                            duplicateIndex.DisplayName(),\n                            duplicateIndex.DeclaringEntityType.DisplayName(),\n                            index.DeclaringEntityType.GetSchemaQualifiedTableName(),\n                            index.GetDatabaseName(storeObject)))\n                    : false\n                : index.GetFilter(storeObject) == duplicateIndex.GetFilter(storeObject)\n                || (shouldThrow\n                    ? throw new InvalidOperationException(\n                        RelationalStrings.DuplicateIndexFiltersMismatch(\n                            index.DisplayName(),\n                            index.DeclaringEntityType.DisplayName(),\n                            duplicateIndex.DisplayName(),\n                            duplicateIndex.DeclaringEntityType.DisplayName(),\n                            index.DeclaringEntityType.GetSchemaQualifiedTableName(),\n                            index.GetDatabaseName(storeObject),","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs#L81-L117","documentation":"Thrown by RelationalIndexExtensions.AreCompatible when two same-named indexes on the same table have matching columns and uniqueness but disagree on descending sort order (IsDescending). A physical index has one collation/sort, so EF rejects conflicting IsDescending configurations under one name.","triggerScenarios":"Lines 94-107: one index has IsDescending null while the other is set, or both are non-null but not SequenceEqual. Produced by calling IsDescending()/IsDescending(true) on one HasIndex and IsDescending(false) (or nothing) on the colliding one.","commonSituations":"Table sharing where one entity uses IsDescending() for descending and the other uses ascending; EF8+ descending-index support added to one entity but not its table-sharing peer; index on composite key where only part of the order differs.","solutions":["Apply the same IsDescending(...) array/value on every index sharing the database name.","If sort orders genuinely differ, rename one index with HasDatabaseName.","Remove the second IsDescending call so both fall back to the default ascending order."],"exampleFix":"// before\nmodelBuilder.Entity<A>().HasIndex(a => new { a.Tenant, a.Name }).IsDescending().HasDatabaseName(\"IX_TN\");\nmodelBuilder.Entity<B>().HasIndex(b => new { b.Tenant, b.Name }).IsDescending(false).HasDatabaseName(\"IX_TN\"); // throws\n\n// after\nmodelBuilder.Entity<B>().HasIndex(b => new { b.Tenant, b.Name }).IsDescending().HasDatabaseName(\"IX_TN\");","handlingStrategy":"validation","validationCode":"// Detect IsDescending mismatches for colliding index names\nvar conflicts = model.GetEntityTypes()\n    .SelectMany(e => e.GetDeclaredIndexes())\n    .Where(i => i.GetDatabaseName() != null)\n    .GroupBy(i => i.GetDatabaseName())\n    .Where(g => g.Select(i => i.IsDescending == null ? \"\" : string.Join(\",\", i.IsDescending)).Distinct().Count() > 1);\nif (conflicts.Any()) throw new InvalidOperationException(\"Sort-order mismatch on shared indexes.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When adopting EF8+ descending indexes on a shared table, apply IsDescending to every colliding index.","Document the chosen sort order next to each shared index declaration."],"tags":["relational","model-validation","index","sort-order"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}