question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is a migration that renames a primary key on a parent table supposed to account for child table foreign keys?

See original GitHub issue

When 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:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
AlilNinjacommented, Jun 8, 2021

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

1reaction
rojicommented, Jun 8, 2021

@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.

Or is a manual intervention in the migration file required to fix the issue?

For now, the easiest workaround would probably be to edit your migration files after they are scaffolded, and either:

  1. Replace the drop/recreate with raw SQL which does a rename (in PG: ALTER TABLE name RENAME CONSTRAINT constraint_name TO new_constraint_name).
  2. Remove the drop/recreate altogether, which will leave your primary key constraint alone. Its name would no longer be consistent with the table, but that has little real consequences.
Read more comments on GitHub >

github_iconTop Results From Across the Web

SQL Foreign key
In this case, table Dept is parent table which has Primary key and will be referenced in child tables having foreign key.
Read more >
Migration: Cannot add foreign key constraint - laravel
The solution was to rename the file with the foreign key to an earlier ... Create base table migration after child migration is...
Read more >
Key migration for physical data modeling
If the primary key takes part in a relationship, then the column is migrated to the child table as a foreign key column....
Read more >
pt-online-schema-change — Percona Toolkit Documentation
The technique of atomically renaming the original and new tables does not work when foreign keys refer to the table. The tool must...
Read more >
Primary and Foreign Keys
The entire primary key must migrate from parent entities to child entities and from supertype, generic entities, to subtypes, category entities. Foreign Keys:...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found