New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seed data migrations don't compensate for on delete cascade #15364
Comments
@smerliere I'm likely not 100% following what you are saying, but if the data did not change between the first and second migration, then there should not be anything to do in the second migration, and hence it should not include the seed data. In other words, the first migration will insert the data, and the second migration does not need to because the first migration already did it. I would only expect to see data inserts/updates in subsequent migrations if the data changes. If this doesn't help, then can you file a small, runnable project/solution that demonstrates the behavior you are seeing so that we can investigate further. |
Thank you for your answer. I send you a runnable project. Don't forget to configure a MariaDB's database (version:10.3) and modify the configuration in appsettings.json In this project, we have three entities that represent our database tables: -MeasureEntity :
-FunctionEntity
-MeasureFunctionEntity (relation many to many between MeasureEntity and FunctionEntity)
There is already an initial migration that you can run with : to create tables and seed associated datas included in ApplicationDbContextSeed.cs To reproduce our problem, you can add a property into MeasureEntity like the following example :
Then, you can create and apply a new migration. You will can see that datas in Measure and Function tables are here. However the table REL_FUNCTION_MEASURE is empty. |
@ajcvickers I am on the same issue and I just tested with SQLite to isolate the problem of MariaDB and Pomelo and I confirm that I have the same problem. At the second migration, the data in the relationship table is empty. |
The issue here is that the FKs on |
@AndriySvyryd Ok I understand why we are losing relationship data. On the other hand I find that your compensation solution is not very practical in the case where we need to change the database several times because it would be necessary to copy / paste the insert data for each relation tables in each new migration. It's just not feasible for a production environment ... It would not be possible to act on this problem with the DeleteBehavior enumerator type? |
@aborderon Sure, you can also change the FKs to |
I tried to add OnDelete.(DeleteBehavior.Restrict) on one relation of the intermediate table like :
But suddenly I get a constraint error during the second update (SQLite Error 19: 'FOREIGN KEY constraint failed'.). On the EF core doc it is specified:
|
@aborderon For SQLite many schema operations are not supported, so you would have to use the first workaround. |
@AndriySvyryd Yes, I realized it right after, I connected the initial Pomelo.MySQL provider to my MariaDB database but I get the same problem during the second update:
I also tried to define the relationship directly on each tables (MeasureEntity and FunctionEntity) but without any possitive results. |
@aborderon Make sure that you are changing the OnDelete value in the same migration as the seed data. Also you can avoid needless reseeding by not setting Post your migrations if you are still having issues. |
Hello @AndriySvyryd , I just did different tests and I understood the problem. Effectively, by removing the On the other hand, I use MariaDB in production database and SQLite in database for unit tests and functional tests. That is to say at the launch of unit tests, migrations and seeds are also launched to be in line with the production environment. The problem is that SQLite obviously does not support the
I also tried to force it with the annotation
I remember why I had forced DateTime.Now on the properties ... Do you have a solution to handle the case of SQLite for testing ? |
@aborderon You can add a default value just for SQLite: if (Database.IsSqlite())
{
builder.Entity<FunctionEntity>().Property(c => c.CreatedDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
builder.Entity<MeasureEntity>().Property(c => c.CreatedDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
builder.Entity<FunctionEntity>().Property(c => c.UpdatedDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
builder.Entity<MeasureEntity>().Property(c => c.UpdatedDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
} |
@AndriySvyryd I had the same idea that you yesterday, it confirms me on my idea ;) Thank you for your help, you can close the ticket. |
…and the FK is set to cascade Fixes #15364
…and the FK is set to cascade Fixes #15364
…and the FK is set to cascade Fixes #15364
Hi,
I have a configuration file that automatically seed data in my database.
After I create a first migration, all tables are filled with data (including relation tables) when I update the database with the following command :
dotnet ef database update
Here is an example of data from migration file that I want to insert in my database :
And here is the data in the seed file :
However when I create a new migration, I found out that relations table are not filled with data from my seed file (FunctionMeasureRelationEntity as exemple) in my database.
I checked the new migration files and I noticed that I didn't find data insertions in my relation table (that I had in my previous migration).
Is that classic comportement from EF Core and I forgot to set some configuration in my code to keep insertion process for my relation tables ?
Further technical details
EF Core version: 2.2.3
Database Provider: Pomelo MySQL
IDE: Visual Studio Code version: 1.33.0
The text was updated successfully, but these errors were encountered: