2017-03-02 156 views
0

我在Asp.net Core中使用了EF,但是在尝试更新时出现了错误。Asp.net核心EF更新

“System.InvalidOperationException”类型发生在 Microsoft.EntityFrameworkCore.dll但在用户代码

附加信息没有处理的一个例外:实体类型“的TodoItem”的实例不能被 因为跟踪具有相同密钥的这种类型的另一个实例是 已被跟踪。添加新实体时,对于大多数密钥类型,如果未设置任何密钥(即,如果 key属性被指定为其类型的默认值),则将创建一个 唯一临时密钥值。如果您为 明确设置新实体的关键值,请确保它们不与 与现有实体冲突或为其他 新实体生成的临时值冲突。在附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文。

这是我的更新代码:

public class TodoRepository : ITodoRepository 
{ 
    private readonly TodoContext _context; 

    public TodoRepository(TodoContext context) 
    { 
     _context = context; 
     //initialize database 
     Add(new TodoItem { Name = "Item1" }); 
     //Add(new TodoItem { Name = "Item2" }); 
     //Add(new TodoItem { Name = "Item3" }); 
    } 

    public IEnumerable<TodoItem> GetAll() 
    { 
     return _context.TodoItems.AsNoTracking().ToList(); 
    } 

    public void Add(TodoItem item) 
    { 
     _context.TodoItems.Add(item); 
     _context.SaveChanges(); 
    } 

    public TodoItem Find(long key) 
    { 
     return _context.TodoItems.AsNoTracking().FirstOrDefault(t => t.Key == key); 
    } 

    public void Remove(long key) 
    { 
     var entity = _context.TodoItems.AsNoTracking().First(t => t.Key == key); 
     _context.TodoItems.Remove(entity); 
     _context.SaveChanges(); 
    } 

    public void Update(TodoItem item) 
    { 
     _context.TodoItems.Update(item); 
     _context.SaveChanges(); 
    } 
} 

正如你会发现,我已经试过AsNoTracking,我也试图在Startup.cs。

public void ConfigureServices(IServiceCollection services) 
{ 
    //inject repository into DI container, use database in memory 
    services.AddDbContext<TodoContext>(options => options.UseInMemoryDatabase().UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)); 

    //inject repository into DI container, and use sql databse 
    //services.AddDbContext<TodoContext>(options=>options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"])); 


    //The first generic type represents the type (typically an interface) that will be requested from the container. 
    //The second generic type represents the concrete type that will be instantiated by the container and used to fulfill such requests. 
    services.AddSingleton<ITodoRepository, TodoRepository>(); 

    //add mvc service to container, this is conventional routing 
    //This also applys to web api which is Attribute Routing 
    services.AddMvc(); 
} 

任何帮助,将不胜感激。

+0

一个更新,如果我注入TodoContext todoContext到我的控制器,并使用'_todoContext.TodoItems.Update(todoItem); _todoContext.SaveChanges(); ',它的工作原理。我不知道为什么它不能在我的TodoRepository下工作。 –

+0

你试过改变数据库条目状态吗?第44行https://github.com/hherzl/Northwind/blob/master/SourceCode/Northwind.Core/DataLayer/Repository.cs –

+0

你正在记忆中工作?如何生成Todoitem.Key的值? InMemory没有任何序列支持,所以如果你不把它们分配到任何地方,所有你的TodoItems都带有Key == 0。 – Dmitry

回答