Change tracker won't assign correct subsequent ID to a newly inserted entity

.net-core asp.net-core c# entity-framework entity-framework-core

Question

I have created a new .NET Core project from the webapi template and added a model class:

public class Todo {
    public int Id { get; set; }
    public string Name { get; set; }
}

My context class:

public SoContext: DbContext {
    public SoContext(DbContextOptions<SoContext> options) { base(options); }
    public DbSet<Todo> Todos { get; set; }
}

I have registered the context like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SoContext>(opt => opt.UseInMemoryDatabase("SO"));
    services.AddMvc();
}

I thought I'd seed the context like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, SoContext context)
{
    app.UseMvc();
    context.Todos.Add(new Todo() { Id = 1, Name = "1" });
    context.SaveChanges(); // This works okay!
}

And it works okay… But then in my request handler, or even directly after in Configure, when I run this:

context.Todos.Add(new Todo() { Name = "non-seed" });
context.SaveChanges(); // Uh - oh

I get:

The instance of entity type 'Todo' cannot be tracked because another instance with the key value is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

The way I see it the change tracker should have figured out to assign the ID of 2 to the non-seed Todo, no? Why isn't it so?

I tried to use Attach instead of add for the entity with the key, even though it doesn't make any sense, and sure enough it made no difference.

Here's a GitHub repository that demonstrates the problem

1
4
9/3/2017 7:34:17 AM

Accepted Answer

UPDATE: This now works in .NET Core 3.0! You can see a showcase here.

I got an answer to this question in a comment in the GitHub repository for EntityFrameworkCore.

When using database-generated keys at the same time as keys chosen by the application it is the responsibility of the application to not choose keys that collide with those generated by the database.

This means that at the moment, either the database is seeded with entities lacking keys (so any relationships need to be set up using navigation properties rather than the IDs) or using raw SQL and letting FE pick up on an already seeded database (thanks, @Nicolaus - although this won't work for in-memory I think).

We could make the key generator in the in-memory database smarter, so leaving this open to discuss in triage, but I think even if we decide to do so, it will likely be low priority.

2
8/22/2019 7:34:21 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow