Asp.net mvc 3 &引用;ObjectStateManager中已存在具有相同密钥的对象…“;将实体状态设置为“已修改”时引发异常
我按照一些示例(包括“Pro ASP.NET MVC 3”和“Professional ASP.NET MVC 3”等书)使用EF 4.1创建简单的ASP.NET MVC 3应用程序(因为我对这些技术不熟悉) 我使用以下存储库(控制器的所有操作方法都使用它的单个实例)来访问数据库:Asp.net mvc 3 &引用;ObjectStateManager中已存在具有相同密钥的对象…“;将实体状态设置为“已修改”时引发异常,asp.net-mvc-3,entity-framework-4,Asp.net Mvc 3,Entity Framework 4,我按照一些示例(包括“Pro ASP.NET MVC 3”和“Professional ASP.NET MVC 3”等书)使用EF 4.1创建简单的ASP.NET MVC 3应用程序(因为我对这些技术不熟悉) 我使用以下存储库(控制器的所有操作方法都使用它的单个实例)来访问数据库: public class ProductRepository : IProductRepository { private readonly EFDbContext _context = ne
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无法跟踪具有相同密钥的多个对象”
我知道这里已经讨论过类似的问题,但我的问题有点不同:
为什么取自示例的代码不起作用(尽管它看起来非常简单和直接)?我可能做错了什么或错过了什么。第一次保存项目时,您似乎没有更新
product.ProductId
。这意味着,当您再次返回保存项目时,它会再次将其添加到上下文中,因此会出现错误
由于该Id将由数据库添加(我假设它是自动生成的Id),因此您需要将产品数据读回客户端。在搜索了几个小时的解决方案后,我在阅读了足够的内容后找到了一个似乎合适的解决方案 修复方法如下: 基本上,从上下文中获取记录并调用:
var currentProduct = _context.Products.Find(product.ProductId);
_context.Entry(currentProduct).CurrentValues.SetValues(product);
这似乎是一个坏主意,在我以前的工作中我一直讨厌EF,但根据Ladislav Mrnka(他显然回答了与Stackoverflow有关的所有EF问题)在这篇文章中的说法:
EF将在内部存储对实体的请求,因此理想情况下,它已经存在,并且不会对数据库进行额外的回调
问题的根本原因似乎是,一旦从上下文中提取产品,上下文就会跟踪它,这就是造成所有问题的原因。因此,将更改合并回是唯一的方法
希望这能有所帮助。从泛型的角度来看,我最近是如何解决同样的问题的:
public TEntity Update(TEntity model, bool persist)
{
if (model == null)
{
throw new ArgumentException("Cannot update a null entity.");
}
var updateModel = Get(model.Id);
if (updateModel == null)
{
return model;
}
this.context.Entry<TEntity>(updateModel).CurrentValues.SetValues(model);
this.Save(persist);
return model;
}
public tenty更新(tenty模型,bool persist)
{
if(model==null)
{
抛出新ArgumentException(“无法更新空实体”);
}
var updateModel=Get(model.Id);
if(updateModel==null)
{
收益模型;
}
this.context.Entry(updateModel).CurrentValues.SetValues(model);
这个。保存(持久化);
收益模型;
}
我在使用Visual Studio为您设置的默认支架时遇到了相同的错误,但我无法解决。若要避免此跟踪,可能会有所帮助。