Skip to content

Migration for updated seed data does not set all enum values converted to string correctly #27575

@ehonda

Description

@ehonda

Overview

Apologies if this is known or expected behaviour, I could not find anything in the documentation or past issues along the lines, but I might of course have missed something. This is regarding some (to us, unexpected) behaviour we encountered when working with migrations and enum property values converted to their string representation in the database. We originally encountered the behaviour using Pomelo.EntityFrameworkCore.MySql provider, but I was also able to reproduce it using Microsoft.EntityFrameworkCore.SqLite in version 6.0.2. Problem description has a short overview of what we observed and expected, and Steps to reproduce contains a link to a small repository demonstrating the reproduction.

Problem description

Observed behaviour

  1. Seed some data (e.g. of type Movie) via OnModelCreating on a DbContext and create a migration.
  2. Add an enum (e.g. Rating, with values Bad = 0 and Good = 1) valued property (e.g. Rating) to Movie and configure that property to have string conversion
  3. Update the seed data Rating values with enum values that correspond to 0 (Bad) and values that correspond to 1 (Good)
  4. Create a subsequent migration. This migration will then only update property Rating values where Good was set, leaving Rating values where Bad was set at the converted default ''.

Here is an example of seed data inserted by taking the above steps, generating a migrations script and applying it to a sqlite database:

sqlite> .dump Movies
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "Movies" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Movies" PRIMARY KEY AUTOINCREMENT,
    "Title" TEXT NOT NULL
, "Rating" TEXT NOT NULL DEFAULT '');
INSERT INTO Movies VALUES(1,'Some Cartoon','Good');
INSERT INTO Movies VALUES(2,'A Documentary','');
COMMIT;

Note the second value inserted: (2,'A Documentary','') - Instead, we would expect (2,'A Documentary','Bad')

Expected behaviour

Both Bad and Good values are set in the subsequent migration. This is consistent with e.g. introducing a new seed Movie with rating Bad (which will be inserted correctly), or configuring the enum to start at value 1, which will cause all converted values to be inserted correctly.

Steps to reproduce

I have uploaded a small repository reproducing the issue here: https://github.com/ehonda/MigrateConvertedEnumZeroes

It contains two commits. The first commit shows the state right after creating the migration seeding initial Movie data. The second commit shows the state right after creating the migration adding the Rating values.

The script generated via dotnet ef migrations script is also included. Here we can see that the part corresponding to the second migration only updates the movie that got rating Good:

BEGIN TRANSACTION;

ALTER TABLE "Movies" ADD "Rating" TEXT NOT NULL DEFAULT '';

UPDATE "Movies" SET "Rating" = 'Good'
WHERE "Id" = 1;
SELECT changes();


INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20220304195711_AddRatingToSeedData', '6.0.2');

COMMIT;

Provider and version information

EF Core version: 6.0.2
Database provider: Microsoft.EntityFrameworkCore.SqLite 6.0.2
Target framework: .NET 6.0
Operating system: Windows 10

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions