First of all, I had to put on stand-by ef core 3 upgrade due to this issue
https://github.com/aspnet/EntityFrameworkCore/issues/18297
duplicate of
https://github.com/aspnet/EntityFrameworkCore/issues/17851
released on 3.1-preview2
Every time I add a migration, all seeded data are updated, so thousand line of code for each migration.
Here it is an example
migrationBuilder.UpdateData(
table: "Countries",
keyColumn: "Id",
keyValue: new Guid("5c60f693-bef5-e011-a587-80ee7300c695"),
columns: new[] { "CurrencyId", "DefaultLanguageId" },
values: new object[] { new Guid("7d76825e-4470-4b45-a5b9-bd96267685c0"), new Guid("deb5f6a8-2e81-47c3-bd10-a89c43919dd7") });
This has happen to me in the past only when i use DateTime.Now in seed because, obviously, the value changes every time I add a migration, but not with GUID
EF Core version:
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: 3.1.100-preview3-014645
Operating system: latest stable VS2019, W10
@ciacco85 Are you hitting the same issue than the one reported in the in the issues you reference? If so, what is the reason for filing this new issue? If not, please post a small, runnable project/solution or complete code listing that demonstrates the behavior you are seeing.
Non at all, the commit associated to the issue solved my issue but, since the issue came from the seeding part, i've thought to quote my previous issues to help you investigating
I've already isolated the code and the issue in a separate branch, so it won't take me a lot to submit the updated code in order to let you inspect the issue
Thanks for the fast answer
3FS.zip
Point to "EFS.Console" project
dotnet-ef migrations add "test-migration"
the added migrations will contains update for all seeded data (expected empty migration)
If you repeat this operation, the new added migration will still contains update for seeded data instead of empty migrations
Since my data model contains base abstract generic classes with seeded data, I think it can be a good complex test you can add to your test's list
@ciacco85 I am not able to restore all the packages for that project, which means I can't run it without hacking on it. Please post a _small_, _runnable_ project/solution or complete code listing so that I can reproduce the behavior you are seeing. This probably means you will need to create a new project in which to isolate the issue.
Sorry about that, I thought I had removed all reference to our private feed and put everything in a self executable project. Now I've fixed it.
I've simplified at most the solution, removing any unnecessary code...trust me, I don't want this issue to be closed, and I hope for a fix before 3.1 release, because I really need the new features released in 3.0/1
Repro step:
point to efs.console
dotnet-ef database update (connection string inside appsettings.json pointing to localhost)
dotnet-ef migrations add Test --> all data seeded is seeded again, here it's an example
if you add another migration, it'll happen the same
I have tried the following without success.
Delete migrations folder --> dotnet-ef migrations add Init --> dotnet-ef update database --> dotnet-ef migrations add Test: same issue
Delete migrations folder --> commented the seed --> dotnet-ef migrations add Init --> dotnet-ef update database --> dotnet-ef migrations add Test: no issue
Delete migrations folder --> commented the seed --> dotnet-ef migrations add Init --> dotnet-ef update database --> dotnet-ef migrations add Test --> manually added data with migrationBuilder.InsertData(..) --> dotnet-ef migrations add Test2: no issue: no issue
This post maybe trivial, but I wanted to inform you
Note for triage: I was able to reproduce this on 3.1 with the code below. The issue appears to be having a GUID with a default value defined.
```C#
public class Blog
{
public Guid Id { get; set; }
public Guid CurrencyId { get; set; }
}
public class BloggingContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test;ConnectRetryCount=0");
}
public static readonly Guid FranceId = new Guid("5C60F693-BEF5-E011-A587-80EE7300C696");
public static readonly Guid EurId = new Guid("7D76825E-4470-4B45-A5B9-BD96267685C0");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>(b =>
{
b.Property(a => a.CurrencyId).HasDefaultValue(EurId); // Remove this ling and the bug goes away
b.HasData(new Blog
{
Id = FranceId,
CurrencyId = EurId,
});
});
}
}
public class Program
{
public static async Task Main()
{
}
}
@ciacco85 3.1 is already complete, so the fix won't be in that release. A workaround that worked for me was to explicitly mark these properties as `ValueGeneratedNever()`. For example:
```C#
b.Property(a => a.CurrencyId).HasDefaultValue(EurId).ValueGeneratedNever();
/cc @AndriySvyryd
Also we shouldn't mark the FK as value generated by convention.
Thank you.
I'll start refactoring seeds and configurations according to your suggestion since it isn't a big deal for the sake of the project following your instructions.
Just 2 questions:
Why have you suggested to avoid mark a FK to generate a value? According to some pattern or convention?
Is there any possibility that this fix will be applied in 3.1.1 instead 5.x?
@ciacco85 The value of the FK is, by its nature, constrained to be the same as the PK that it is associated with. This means that it is very rare to generate a value for the FK itself. Instead if the value is unknown then it is propagated from the associated PK. The value of the PK may have been generated, but the value for the FK is not itself generated.
It's unlikely that we will patch this because using .ValueGeneratedNever(); is a reasonable workaround. However, we could always revisit this if we get more reports or learn something new about the issue.
Following your suggestion completely solved my issue.
I was able to fully migrate to EF Core 3.1 preview 3 and deploy to Azure App Service through DevOps pipeline with the proper official Extensions
Thanks for the deep and exhaustive explanation and I agree with the the fact that .ValueGeneratedNever(); is a reasonable workaround
But, since it wasn't happening in 2.x version, maybe you could evaluate @AndriySvyryd idea and mark all FK as .ValueGeneratedNever(); default every time an .HasDefaultValue(...) is called.
I won't close the issue, I think it's your decision
@ciacco85 Glad you were able to get it working. Agreed that there a changes needed here--hence the issue is still open and in 5.0.
I got a similar problem:
Since Microsoft.EntityFrameworkCore 3.1.0 the command "Add-Migration" updates every seeded row having a colum with a default value and using this column in the seed method.
Example:
public class ChallengeSettings
{
public int Id { get; set; }
public int MinNumber { get; set; }
}
modelBuilder.Entity<ChallengeSettings>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.MinNumber)
.HasDefaultValue(1);
});
modelBuilder.Entity<ChallengeSettings>().HasData(
new ChallengeSettings { Id = -1, MinNumber = 50 },
new ChallengeSettings { Id = -2, MinNumber = 1 },
new ChallengeSettings { Id = -3, MinNumber = 5 }
);
The migration:
public partial class Test : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -3,
column: "MinNumber",
value: 5);
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -2,
column: "MinNumber",
value: 1);
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -1,
column: "MinNumber",
value: 50);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -3,
column: "MinNumber",
value: 5);
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -2,
column: "MinNumber",
value: 1);
migrationBuilder.UpdateData(
table: "ChallengeSettings",
keyColumn: "Id",
keyValue: -1,
column: "MinNumber",
value: 50);
}
}
The code of my program is much bigger so it can be pretty hard to always remove these "wrong" migrations (cause I wanted the migration to happen only at the beginning, so I can update these seeded values later without them getting overrided on every migration).
Problem occured with:
EFCore 3.1.0 and 3.1.1.
Npgsql.EntityFrameworkCore.PostgreSQL 3.1.0
Worked with:
EFCore 3.0.2
Npgsql.EntityFrameworkCore.PostgreSQL 3.0.1
It could be Npgsql, too - can't test it because Npgsql depends on EFCores specific versions.
Fixed in a8f0f4c4dfc94975bd318a6b5a5d3a627df1d5ba
Most helpful comment
Fixed in a8f0f4c4dfc94975bd318a6b5a5d3a627df1d5ba