我按照一些示例(包括诸如“Pro ASP.NET MVC 3”和“Professional ASP.NET MVC 3”之类的书籍)使用 EF 4.1 创建了简单的 ASP.NET MVC 3 应用程序(因为我是这些技术的新手)。
我正在使用以下存储库( Controller 的所有操作方法都使用它的单个实例)来访问数据库:
public class ProductRepository : IProductRepository
{
private readonly EFDbContext _context = new EFDbContext();
#region Implementation of IProductRepository
....
public void SaveProduct(Product product)
{
if (product.ProductId == 0)
{
_context.Products.Add(product);
}
else
{
_context.Entry(product).State = EntityState.Modified;
}
_context.SaveChanges();
}
....
}
该存储库执行更新,如我使用的示例中所示。
产品类别:
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
在更新产品的情况下,我收到异常“ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象”
我知道这里已经讨论过类似的问题,但我的问题有点不同:
为什么这个代码 取自示例 不工作(虽然它看起来非常简单明了)?我可能做错了什么或错过了什么。
最佳答案
在寻找解决方案数小时后,在阅读足够多的内容后,我找到了一个似乎合适的解决方案。
修复方法在这里:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key
基本上,从上下文中获取记录并调用:
var currentProduct = _context.Products.Find(product.ProductId);
_context.Entry(currentProduct).CurrentValues.SetValues(product);
这似乎是一个坏主意,而且我在以前的工作中一直讨厌 EF,但根据 Ladislav Mrnka(他显然在 Stackoverflow 上回答了每个 EF 相关问题)在这篇文章中的说法:
Entity Framework and Connection Pooling
EF 将在内部存储对实体的请求,因此理想情况下,它已经存在并且不会对数据库进行额外的回调。
问题的根本原因似乎是,一旦从上下文中获取产品,上下文就会跟踪它,这就是导致所有麻烦的原因。因此,将您的更改重新合并是唯一的方法。
希望有帮助。
关于asp.net-mvc-3 - "An object with the same key already exists in the ObjectStateManager..."将实体状态设置为已修改时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7221349/