At the moment, I'm experiencing an issue where I can create a migration, which has data updates, but the DbContextModelSnapshot
has this data. When you look at the updates in the migration, they've already been applied to the DbContextModelSnapshot
and the database.
A coworker created a migration about 3 months ago, and everything has been fine. We've created several more migrations since then, and haven't experienced this issue. However, the last couple days, we have been experiencing this.
We've tried creating a migration with this data update, and running it. But when we create another migration, that data update is there again. None of us have experienced this issue before.
How can we create migrations without having this data keep showing up? I'm not sure what code would be relevant to show for this.
EDIT:
Migrations are created that have Data A (pre-existing data in the database and DbContextModelSnapshot
) and Data B (new Data), and are completely successfully. By that, I mean that Data B is added to the database and the DbContextModelSnapshot
without issue. However, when I create another migration, Data A shows up again.
EDIT 2:
As requested, I've looked at all the migrations we have and compared to the __EFMigrationsHistory
, and they are all there. Every migration has been run successfully. This was verified by at least 3 people.
EDIT 3:
Okay, the question asked was how am I specifying the data for the migrations. In the model class, we've got our Configure()
. Here's it, and the subsequent functions:
internal static void Configure(EntityTypeBuilder<PlayerType> entityTypeBuilder)
{
SetDefaultValues(entityTypeBuilder);
LoadSeedData(entityTypeBuilder);
}
private static void LoadSeedData(EntityTypeBuilder<PlayerType> entityTypeBuilder)
{
void AddPlayerType(int playerTypeId, string name, DateTime createdDate, DateTime? modifiedDate = null, bool isSystemDefault = true)
{
entityTypeBuilder
.HasData(
DbContextHelper.AssignBaseStats(
new List<PlayerType>
{
new PlayerType()
{
PlayerTypeId = playerTypeId,
Name = name,
IsSystemDefault = isSystemDefault
},
},
createdDate,
!modifiedDate.HasValue ? createdDate : modifiedDate.Value,
ApplicationConstants.SeedDataGenerationIdentifier,
false));
}
AddPlayerType(ApplicationConstants.TitleId, "Title", new DateTime(2020, 2, 11, 16, 27, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc));
AddPlayerType(ApplicationConstants.BaseId, "Base", new DateTime(2020, 2, 11, 16, 27, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc));
AddPlayerType(ApplicationConstants.QuizId, "Quiz", new DateTime(2020, 2, 11, 16, 27, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc));
AddPlayerType(ApplicationConstants.ThreeDId, "ThreeDModel", new DateTime(2020, 2, 11, 16, 27, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc), false);
AddPlayerType(ApplicationConstants.TestId, "Test", new DateTime(2020, 2, 11, 16, 27, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc), false);
AddPlayerType(ApplicationConstants.ScoreId, "Score", new DateTime(2020, 3, 25, 21, 59, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc));
AddPlayerType(ApplicationConstants.ExitId, "Exit", new DateTime(2020, 3, 25, 21, 59, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc));
AddPlayerType(ApplicationConstants.WalkId, "Walkaround", new DateTime(2020, 10, 22, 14, 44, 0, 0, DateTimeKind.Utc),
new DateTime(2020, 12, 19, 20, 11, 0, 0, DateTimeKind.Utc), false);
}
private static void SetDefaultValues(EntityTypeBuilder<PlayerType> entityTypeBuilder)
{
entityTypeBuilder
.Property(thisTable => thisTable.IsSystemDefault)
.HasDefaultValue(false);
}
Now, this was updated back in mid-December, and all migrations after have been fine. But as stated, recent migrations have started having the following:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
schema: "LessonDesigner",
table: "PlayerType",
keyColumn: "PlayerTypeId",
keyValue: 1,
column: "IsSystemDefault",
value: true);
migrationBuilder.UpdateData(
schema: "LessonDesigner",
table: "PlayerType",
keyColumn: "PlayerTypeId",
keyValue: 2,
column: "IsSystemDefault",
value: true);
migrationBuilder.UpdateData(
schema: "LessonDesigner",
table: "PlayerType",
keyColumn: "PlayerTypeId",
keyValue: 3,
column: "IsSystemDefault",
value: true);
migrationBuilder.UpdateData(
schema: "LessonDesigner",
table: "PlayerType",
keyColumn: "PlayerTypeId",
keyValue: 6,
column: "IsSystemDefault",
value: true);
migrationBuilder.UpdateData(
schema: "LessonDesigner",
table: "PlayerType",
keyColumn: "PlayerTypeId",
keyValue: 7,
column: "IsSystemDefault",
value: true);
}
EDIT 4:
Here's screenshots to show the back-to-back created migrations. You can see, the Up()
is identical:
The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.
Open the Package Manager Console from Tools → Library Package Manager → Package Manager Console and then run the enable-migrations –EnableAutomaticMigration:$true command (make sure that the default project is the project where your context class is).
Delete your Migrations folder. Create a new migration and generate a SQL script for it. In your database, delete all rows from the migrations history table. Insert a single row into the migrations history, to record that the first migration has already been applied, since your tables are already there.
You seem to be using some EFC 3.1 version (up to 3.1.9 inclusive) which exhibits the bug #21661 - Using ValueGeneratedOnAdd
on a property that is seeded causes UpdateData
calls in every subsequent migration, fixed in 3.1.10+ by #22760 - [release/3.1] Fix issue where property with value generated on add is reseeded in every migration.
Note that every property having HasDefaultValue{Sql}
like your IsSystemDefault
is considered ValueGeneratedOnAdd
by convention.
Now, to resolve the problem, either upgrade to EFC 3.10 or later, or use the following workaround with ValueGeneratedNever
:
entityTypeBuilder
.Property(thisTable => thisTable.IsSystemDefault)
.HasDefaultValue(false)
.ValueGeneratedNever(); // <-- add this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With