{"record":{"id":"ae7030c7bd72a5b4","repo":"dotnet/efcore","slug":"the-indexes-index1-on-entitytype1-and-index-ae7030","errorCode":null,"errorMessage":"The indexes {index1} on '{entityType1}' and {index2} on '{entityType2}' are both mapped to '{table}.{indexName}', but with different filters ('{filter1}' and '{filter2}').","messagePattern":"The indexes (.+?) on '(.+?)' and (.+?) on '(.+?)' are both mapped to '(.+?)\\.(.+?)', but with different filters \\('(.+?)' and '(.+?)'\\)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs","lineNumber":110,"sourceCode":"                        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),\n                            index.GetFilter(),\n                            duplicateIndex.GetFilter()))\n                    : false);\n    }\n\n    private static string FormatColumnNames(IEnumerable<string> columnNames)\n        => \"{\" + string.Join(\", \", columnNames.Select(n => \"'\" + n + \"'\")) + \"}\";\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs#L92-L128","documentation":"Thrown by RelationalIndexExtensions.AreCompatible when two same-named indexes on the same table match on columns, uniqueness, and sort order but disagree on the SQL filter (GetFilter). Because a filtered index is one physical object, EF rejects conflicting HasFilter values under one name.","triggerScenarios":"Line 108-119: index.GetFilter(storeObject) != duplicateIndex.GetFilter(storeObject). Produced when HasFilter(\"...\") is set on one HasIndex but not, or differently, on a colliding index across table-sharing entity types.","commonSituations":"Soft-delete columns where one entity filters out deleted rows and the co-mapped entity does not; SQL Server filtered indexes declared on one entity only; cross-provider migrations where a filter string was provider-specific and drifted.","solutions":["Apply the identical HasFilter SQL on every index sharing the database name.","Remove the HasFilter from both so the index becomes unfiltered consistently.","If filters must differ, give the indexes distinct HasDatabaseName values."],"exampleFix":"// before\nmodelBuilder.Entity<Doc>().HasIndex(d => d.Title).HasFilter(\"[Title] IS NOT NULL\").HasDatabaseName(\"IX_Title\");\nmodelBuilder.Entity<Archive>().HasIndex(a => a.Title).HasDatabaseName(\"IX_Title\"); // unfiltered -> throws\n\n// after\nmodelBuilder.Entity<Archive>().HasIndex(a => a.Title).HasFilter(\"[Title] IS NOT NULL\").HasDatabaseName(\"IX_Title\");","handlingStrategy":"validation","validationCode":"// Detect HasFilter mismatches among same-named indexes\nvar bad = model.GetEntityTypes()\n    .SelectMany(e => e.GetDeclaredIndexes())\n    .GroupBy(i => i.GetDatabaseName())\n    .Where(g => g.Select(i => i.GetFilter() ?? \"\").Distinct().Count() > 1)\n    .Select(g => g.Key);\nif (bad.Any()) throw new InvalidOperationException(\"Filter mismatch: \" + string.Join(\", \", bad));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep filter SQL in a shared constant and reuse it for every colliding index.","Prefer provider-agnostic filter expressions where possible."],"tags":["relational","model-validation","index","filter"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}