Is a migration that renames a primary key on a parent table supposed to account for child table foreign keys?
See original GitHub issueWhen moving from EF Core 3.1.7 to EF Core 5.0.5 the naming conventions around pluralization of primary keys/indexes changed slightly, so we needed to generate a migration to update our names. One primary key in particular is causing a problem because there’s another table that has a foreign key that references it. The scenario in pseudocode is pretty basic (should be anything where a parent table has a primary key and there’s a child table that has a foreign key to the parent primary key - though in my case it’s a one-to-many relationship):
public class Foo : IKeyedEntity
{
public Guid Id //parent table primary key
public string FooName
public int FooNumber
public IReadOnlyCollection<Bar> Bars //one-to-many child table
}
public class Bar : IKeyedEntity
{
public Guid Id
public enum BarType
public Guid FooId //child table foreign key on the parent table's primary key
}
The migration generates fine, but only includes the rename for the primary key. Because of that, when we run the migration and the default “renaming” of dropping the key and then re-adding it happens, the migration errors out saying it can't drop the constraint because other objects depend on it
. This is because the migration script isn’t taking into account that it needs to drop the child table’s foreign key before the parent table primary key can be dropped. Right now I have two solutions/workarounds:
- manually edit the migration so that it drops the foreign key on the child table first, then does the drop and re-add of the parent table primary key, then add the foreign key back
- Add a
.HasName
to the Primary key in question to lock in the name so it doesn’t have to change
My question is: is this how it’s supposed to work? Is it expected that EF Core doesn’t pick up foreign keys on a primary key name change and you have to manually edit the migration to fix it? Or is there some sort of configuration I’m missing and I could tell entity framework to generate the drop and re-add for the child table foreign key as well? (basically manual fix option 1 but automatically)
Other info: The closest thing I could find to my problem was issue #15084 except they’re talking about renaming a column rather than a key on an existing column. Issue #13178 that was linked about foreign keys is also about changing a column’s property rather than a key EF Core version: 3.1.7, 5.0.5 (what we’re migrating from and to, but the same migration is generated in both) Database provider: Npgsql.EntityFrameworkCore.PostgreSQL Target framework: .NET 5.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Oh! I get it now. For some reason I thought all the talk of dropping+recreating being the norm meant that a rename operation for primary keys didn’t exist. My bad XD
I went with the raw SQL option since it takes care of the problem and is super straightforward, and it worked splendidly. Thanks!
TLDR for anyone looking at this in the future: as of the time of this issue, entity framework doesn’t automatically account for it and you must fix it manually, but a raw SQL rename is an easy fix
@AlilNinja the point is that if we rename a primary key instead of dropping and re-creating it, nothing would need to be done to the foreign keys which point to it - the problem is specifically with the dropping of a referenced foreign key. Now, there may be some other scenarios which could require dropping and recreating a primary key (e.g. changing its type or some other facet, such as SQL Server identity), but any scenario which can be handled via renaming should probably be done that way.
For now, the easiest workaround would probably be to edit your migration files after they are scaffolded, and either:
ALTER TABLE name RENAME CONSTRAINT constraint_name TO new_constraint_name
).