Skip to content
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

HasData() creating deletes and re-inserts for unchanged entities on subsequent migrations #13154

Closed
collinbarrett opened this issue Aug 29, 2018 · 11 comments
Labels
closed-fixed type-bug
Milestone

Comments

@collinbarrett
Copy link

@collinbarrett collinbarrett commented Aug 29, 2018

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. collinbarrett/FilterLists@3786c83 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. collinbarrett/FilterLists@f241d3e 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. collinbarrett/FilterLists@e227e33 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 #11597 / PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#601), I tried temporarily converting all of these to ints, with the same results.

  1. collinbarrett/FilterLists@4d7049d Convert types.
  2. collinbarrett/FilterLists@f4720da Initial migration.
  3. collinbarrett/FilterLists@7f8bcfa 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: #11969)

  1. collinbarrett/FilterLists@df5c135 Remove DateTime.Now().
  2. collinbarrett/FilterLists@0f8fdd3 Initial migration.
  3. collinbarrett/FilterLists@cbfda72 Second migration (shows deletes and re-inserts).

Alternate 3: Alternate 1 + Alternate 2 (per)

  1. Branched from Alternate 1 (pre-migrations)
  2. collinbarrett/FilterLists@fd33cba Remove DateTime.Now().
  3. collinbarrett/FilterLists@da5ae2b Initial migration.
  4. collinbarrett/FilterLists@0629881 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

@AndriySvyryd
Copy link
Member

@AndriySvyryd AndriySvyryd commented Aug 29, 2018

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

@collinbarrett
Copy link
Author

@collinbarrett collinbarrett commented Aug 29, 2018

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

collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Aug 29, 2018
collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Aug 29, 2018
collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Aug 29, 2018
@collinbarrett
Copy link
Author

@collinbarrett collinbarrett commented Aug 29, 2018

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

@chrispickford
Copy link

@chrispickford chrispickford commented Sep 25, 2018

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

@collinbarrett
Copy link
Author

@collinbarrett collinbarrett commented Sep 25, 2018

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

@chrispickford
Copy link

@chrispickford chrispickford commented Sep 25, 2018

@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);
});

@collinbarrett
Copy link
Author

@collinbarrett collinbarrett commented Sep 25, 2018

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?

@chrispickford
Copy link

@chrispickford chrispickford commented Sep 25, 2018

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")}
};

@kalebpol
Copy link

@kalebpol kalebpol commented Oct 11, 2018

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.

@ajcvickers ajcvickers modified the milestones: 2.2.0-preview3, 2.2.0 Oct 15, 2018
collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Oct 17, 2018
collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Oct 17, 2018
collinbarrett added a commit to collinbarrett/FilterLists that referenced this issue Oct 17, 2018
@AndriySvyryd
Copy link
Member

@AndriySvyryd AndriySvyryd commented Oct 18, 2018

"Alternate 2" now works correctly with the latest nightly build. Probably fixed by c8e4996

@AndriySvyryd AndriySvyryd removed their assignment Oct 18, 2018
@AndriySvyryd AndriySvyryd added the closed-fixed label Oct 18, 2018
@collinbarrett
Copy link
Author

@collinbarrett collinbarrett commented Oct 18, 2018

Thanks! Will test that out.

Issue is related to #13172

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed type-bug
Projects
None yet
Development

No branches or pull requests

5 participants