更改跟踪器将不正确后续的ID分配给

问题描述:

我创建从webapi模板创建新的.NET核心项目,并增加了一个模型类新插入的实体:更改跟踪器将不正确后续的ID分配给

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

我的上下文类:

我已经注册的背景是这样的:

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

我想我会种子共NTEXT这样的:

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! 
} 

和它的作品好了......但后来在我的请求处理程序,甚至在Configure,直接后,当我运行此:

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

我得到:

实体类型'Todo'的实例无法跟踪,因为具有键值的另一个实例已被跟踪。在附加现有实体时,请确保仅附加具有给定键值的一个实体实例。

我看到它的变化跟踪器应该已经找到了指定的2non-seedTodo的ID,没有的方式?为什么不是这样?

我试着使用Attach而不是添加具有该键的实体,即使它没有任何意义,并且肯定它没有区别。

Here's a GitHub repository that demonstrates the problem

+0

它是否适用于'new Todo(){Id = 2,Name =“non-seed”}'? –

+0

它没有。我启用了敏感日志记录,它告诉我冲突的ID是'1'。 –

+0

对不起,我不认识你正在使用EF 2.0。 – Nikolaus

我在comment in the GitHub repository for EntityFrameworkCore得到的回答了这个问题。

当数据库生成的密钥与应用程序选择的密钥同时使用时,应用程序有责任不选择与数据库生成的密钥相冲突的密钥。

这意味着,在目前,无论是数据库接种实体缺乏键(所以任何关系,必须建立使用导航属性,而非标识),或使用原始SQL,并让FE拿起一个已经播种了数据库(谢谢,@Nicolaus - 尽管这对我认为的内存无效)。

我们可以使密钥生成器在内存数据库更聪明,所以离开这个开放的分流讨论,但我认为即使我们决定这样做,它可能会低优先级。

+2

如果您希望您的上下文使用显式标识进行播种,则可以使用“标识插入开启”与事务处理的交易。 – Nikolaus

+0

您正在考虑在SQL中种子,然后让EF接手已经播种的数据库,对吧?好主意,但我没有SQL种子,我拥有的格式更适合导航属性方法。无论哪种方式,谢谢。编辑。 –

+2

不,我不想用种子与SQL看看这个:https://*.com/questions/39023922/ef-7-identity-insert-issue – Nikolaus