Efcore: HasData() creating deletes and re-inserts for unchanged entities on subsequent migrations

Created on 29 Aug 2018  路  11Comments  路  Source: dotnet/efcore

Issue

When I add a migration after filling out some HasData() on a modelBuilder.Entity<T>(), the migration works well. However, if I add another migration immediately following (without changing anything), the second migration deletes and re-inserts all of the seed data again.

Background

I asked a SO question yesterday, because I thought this was occurring because I was trying to seed from an external data source (.json files). However, I am seeing the same issue today with inline new-ing of seed data as the docs demonstrate.

Any given piece of seed data, if left unmodified in HasData(), should only appear in Up() of a single migration, correct? This is my first go at using EF Core migrations with seed data, so it is certainly possible that I have something configured incorrectly, or I missed something in how the feature is supposed to work.

This could very well be a Pomelo (provider) issue as well. I am not versed enough in EF Core to know how to discern which it might be.

Steps to reproduce

  1. https://github.com/collinbarrett/FilterLists/commit/3786c835339e3663370b4225fc3fd05884d945cd Add the seed data. (I've seen suggested to use anonymous types to handle related data, but I did test with concrete types with the same result.)
  2. https://github.com/collinbarrett/FilterLists/commit/f241d3e928701682fa0356f356671eb81fe05644 Then I add the first migration, which looks/works great.
  3. Apply the migration by running the project which includes a call to MyDbContext.Database.Migrate();. Verified that seed data was successfully added to the db.
  4. https://github.com/collinbarrett/FilterLists/commit/e227e333d7be4607e1bb9b612c44b24a5952f670 Then, I immediately try adding another migration with no changes to the code, which (presumably erroneously) deletes and re-inserts all of the data.

Alternate 1: uint -> int for Ids

Since I am somewhat swimming upstream using uints as Id types (blocked by https://github.com/aspnet/EntityFrameworkCore/issues/11597 / https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/601), I tried temporarily converting all of these to ints, with the same results.

  1. https://github.com/collinbarrett/FilterLists/commit/4d7049d93b5a9aa3abdcff66eb89a3547b6887cf Convert types.
  2. https://github.com/collinbarrett/FilterLists/commit/f4720da3b394ea6e05d4a539c1a3ffbb6f843214 Initial migration.
  3. https://github.com/collinbarrett/FilterLists/commit/7f8bcfa9ded3ed89718e957ac47283efcc10ee1d Second migration (shows deletes and re-inserts).

Alternate 2: removing dynamic DateTime/Timestamp

Because I do have a couple DateTimes stored as Timestamps in this entity, I tried a variant removing the DateTime.Now calculation of these values thinking that the dynamic nature of these properties caused a re-generation of the seed data in the migration. (ref: https://github.com/aspnet/EntityFrameworkCore/issues/11969)

  1. https://github.com/collinbarrett/FilterLists/commit/df5c1354f0440e0dde772369d9976f01876bc207 Remove DateTime.Now().
  2. https://github.com/collinbarrett/FilterLists/commit/0f8fdd3474e8aae07abbdd9a31da617d65c6372d Initial migration.
  3. https://github.com/collinbarrett/FilterLists/commit/cbfda72ea1ae824a052fffe57619bc8f1b9b0c4a Second migration (shows deletes and re-inserts).

Alternate 3: Alternate 1 + Alternate 2 (per)

  1. Branched from Alternate 1 (pre-migrations)
  2. https://github.com/collinbarrett/FilterLists/commit/fd33cbae49d73701b37d55a35899679bc0531a3b Remove DateTime.Now().
  3. https://github.com/collinbarrett/FilterLists/commit/da5ae2bdf4cb17f2819a2646bad7c553c5ddafeb Initial migration.
  4. https://github.com/collinbarrett/FilterLists/commit/062988110eb58b207a04bd840f7d5cfdf9f1dd75 Second migration (shows deletes and re-inserts).

Further technical details

EF Core version: 2.1.1
Database Provider: Pomelo.EntityFrameworkCore.MySql (2.1.1)
Operating system: Windows 10
IDE: Visual Studio 2017 15.8.2

closed-fixed type-bug

All 11 comments

@collinbarrett Did you try using int Ids __and__ removing dynamic temporal values at the same time?

@AndriySvyryd Good suggestion. Should've thought to try that. Will try that and provide any updates.

@AndriySvyryd added "Alternate 3" to the OP. No dice.

Also experiencing this exact same issue, will endeavour to remove the duplicated InsertData and DeleteData statements from generated migrations until 2.2.0 drops.

@chrispickford , which EF Provider are you using? Curious if it might be provider-specific or EF Core in general.

@collinbarrett Here's my context factory, I'm using SqlServer:

public class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
  public MyContext CreateDbContext(string[] args)
  {
    var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
    optionsBuilder.UseSqlServer(@"Server=.\SQLEXPRESS;Database=Test;Trusted_Connection=True;");

    return new MyContext(optionsBuilder.Options);
  }
}

In MyContext.cs, nothing fancy going on:

modelBuilder.Entity<Brand>(b =>
{
  b.HasData(SeedData.BrandData);
});

Ok, I'm using Pomelo for MySQL, which is a bit off the main trail of SQL Server. So, I was thinking it could be a bug with that provider. So, thanks for verifying it occurs with SQL Server as well.

Is SeedData.BrandData just hard-coded new-ed data similar to what I was doing here?

Yes, just another static class for seed data, exactly like yours in fact.

I thought it might be due to using dynamic values, i.e. Guid.NewGuid(), I've since changed to using static hard-coded values and the issue still occurs.

internal static readonly Brand[] BrandData =
{
  new Brand {Id = 1, Name = "Brand X", Uuid = new Guid("e5f9762f-44ce-456e-b226-c8b2ae733f72")}
};

Yeah, i have this problem too. The migrations are created just fine when the primary key is an int, but with the entities that have a string as primary key the migrations delete and re-insert the data instead of updating it.

"Alternate 2" now works correctly with the latest nightly build. Probably fixed by https://github.com/aspnet/EntityFrameworkCore/commit/c8e49968c7aa60a8e0f32da3ecedad5e7ffa3b59

Thanks! Will test that out.

Issue is related to https://github.com/aspnet/EntityFrameworkCore/issues/13172

Was this page helpful?
0 / 5 - 0 ratings