{"record":{"id":"26f83430d76c3814","repo":"dotnet/efcore","slug":"the-foreign-keys-foreignkeyproperties1-on-enti-26f834","errorCode":null,"errorMessage":"The foreign keys {foreignKeyProperties1} on '{entityType1}' and {foreignKeyProperties2} on '{entityType2}' are both mapped to '{table}.{foreignKeyName}', but referencing different principal columns ({principalColumnNames1} and {principalColumnNames2}).","messagePattern":"The foreign keys (.+?) on '(.+?)' and (.+?) on '(.+?)' are both mapped to '(.+?)\\.(.+?)', but referencing different principal columns \\((.+?) and (.+?)\\)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs","lineNumber":101,"sourceCode":"        {\n            return shouldThrow\n                ? throw new InvalidOperationException(\n                    RelationalStrings.DuplicateForeignKeyColumnMismatch(\n                        foreignKey.Properties.Format(),\n                        foreignKey.DeclaringEntityType.DisplayName(),\n                        duplicateForeignKey.Properties.Format(),\n                        duplicateForeignKey.DeclaringEntityType.DisplayName(),\n                        foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),\n                        foreignKey.GetConstraintName(storeObject, principalTable.Value),\n                        foreignKey.Properties.FormatColumns(storeObject),\n                        duplicateForeignKey.Properties.FormatColumns(storeObject)))\n                : false;\n        }\n\n        if (!principalColumns.SequenceEqual(duplicatePrincipalColumns))\n        {\n            return shouldThrow\n                ? throw new InvalidOperationException(\n                    RelationalStrings.DuplicateForeignKeyPrincipalColumnMismatch(\n                        foreignKey.Properties.Format(),\n                        foreignKey.DeclaringEntityType.DisplayName(),\n                        duplicateForeignKey.Properties.Format(),\n                        duplicateForeignKey.DeclaringEntityType.DisplayName(),\n                        foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),\n                        foreignKey.GetConstraintName(storeObject, principalTable.Value),\n                        foreignKey.PrincipalKey.Properties.FormatColumns(principalTable.Value),\n                        duplicateForeignKey.PrincipalKey.Properties.FormatColumns(principalTable.Value)))\n                : false;\n        }\n\n        if (foreignKey.IsUnique != duplicateForeignKey.IsUnique)\n        {\n            return shouldThrow\n                ? throw new InvalidOperationException(\n                    RelationalStrings.DuplicateForeignKeyUniquenessMismatch(\n                        foreignKey.Properties.Format(),","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs#L83-L119","documentation":"Thrown by AreCompatible when two foreign keys share name, tables, and dependent columns, but the principal-side referenced columns differ. The single FK constraint can target only one principal column set, so the mismatch is rejected.","triggerScenarios":"Two same-named FKs point at the same principal table but reference different principal columns — e.g. one targets the primary key and another targets an alternate key, yet both got the same constraint name.","commonSituations":"Switching a FK from referencing the PK to an alternate key (HasPrincipalKey) without renaming the constraint. TPH/table-splitting where shared FKs disagree on the principal key.","solutions":["Make both FKs reference the same principal key (same principal columns).","Assign distinct HasConstraintName values so each FK targets its own principal key.","Verify HasPrincipalKey configuration is consistent across the colliding FKs.","Audit principal column names via PrincipalKey.Properties.GetColumnNames."],"exampleFix":"// before (one FK targets PK Id, the other targets alt key Code, same name)\nmodelBuilder.Entity<Order>().HasOne(o => o.Customer)\n    .WithMany().HasForeignKey(o => o.CustomerId).HasConstraintName(\"FK_Order_Customer\");\nmodelBuilder.Entity<Order>().HasOne(o => o.CustomerByCode)\n    .WithMany().HasForeignKey(o => o.CustomerCode)\n    .HasPrincipalKey(c => c.Code).HasConstraintName(\"FK_Order_Customer\");\n\n// after\nmodelBuilder.Entity<Order>().HasOne(o => o.CustomerByCode)\n    .WithMany().HasForeignKey(o => o.CustomerCode)\n    .HasPrincipalKey(c => c.Code).HasConstraintName(\"FK_Order_Customer_Code\");","handlingStrategy":"validation","validationCode":"// Verify FKs sharing a name reference the same principal key columns\nforeach (var g in allFks.GroupBy(fk => fk.GetConstraintName()))\n{\n    var principalCols = g.Select(fk => string.Join(\",\", fk.PrincipalKey.Properties.GetColumnNames(store))).Distinct();\n    if (principalCols.Count() > 1)\n        throw new InvalidOperationException($\"FK {g.Key} references different principal columns.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep HasPrincipalKey consistent across FKs that reuse a constraint name.","When switching an FK to an alternate key, also rename the constraint.","Validate the model in tests so principal-key mismatches surface early."],"tags":["efcore","foreign-key","principal-key","model-validation","duplicate"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}