gpt4 book ai didi

asp.net-mvc-3 - Entity Framework 代码优先 : "The ObjectStateManager cannot track multiple objects with the same key."

转载 作者:行者123 更新时间:2023-12-04 16:55:00 25 4
gpt4 key购买 nike

我在 MVC3 中遇到了 Entity Framework 代码优先的问题。我遇到了这个异常(exception):

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.



这在 SO 上已多次解决,但在我的情况下,我无法使用任何建议的解决方案。

这是一个代码示例:
FestORM.SaleMethod method = new FestORM.SaleMethod
{
Id = 2,
Name = "Test Sale Method"
};
FestContext context = new FestContext();

//everything works without this line:
string thisQueryWillMessThingsUp =
context.SaleMethods.Where(m => m.Id == 2).Single().Name;

context.Entry(method).State = System.Data.EntityState.Modified;
context.SaveChanges();

编辑以澄清:我正在尝试更新数据库中已存在的对象。

没有代码中注明的查询,一切正常。 在我的应用程序中,我的 Controller 正在实例化上下文,并且相同的上下文被传递到 Controller 使用的几个存储库——所以我不能简单地为初始查询操作使用不同的上下文。我试图从 ObjectStateManager 中的跟踪中删除实体,但我似乎也无法获得任何东西。我试图找出一个对这两种情况都适用的解决方案:有时我会更新一个由 ObjectStateManager 跟踪的对象,有时它碰巧还没有被跟踪。

FWIW,我真正的存储库功能是这样的,就像上面的代码:
public void Update(T entity)
{
//works ONLY when entity is not tracked by ObjectStateManager
_context.Entry(entity).State = System.Data.EntityState.Modified;
}

public void SaveChanges()
{
_context.SaveChanges();
}

有任何想法吗?我已经和这个斗争了太久了......

最佳答案

问题是这个查询

string thisQueryWillMessThingsUp =  
context.SaleMethods.Where(m => m.Id == 2).Single().Name;

将 SaleMethod 实体的一个实例带入上下文,然后这段代码
context.Entry(method).State = System.Data.EntityState.Modified;

将不同的实例附加到上下文。两个实例具有相同的主键,因此 EF 认为您正在尝试将具有相同键的两个不同实体附加到上下文。它不知道它们应该是同一个实体。

如果由于某种原因您只需要查询名称,但不想实际将完整实体带入上下文,那么您可以这样做:
string thisQueryWillMessThingsUp =           
context.SaleMethods.Where(m => m.Id == 2).AsNoTracking().Single().Name;

如果您要做的是更新现有实体,并且您拥有该实体的所有映射属性的值,那么最简单的做法是不运行查询而只使用:
context.Entry(method).State = System.Data.EntityState.Modified;

如果您不想更新所有属性,可能是因为您没有所有属性的值,那么在调用 SaveChanges 之前查询实体并在其上设置属性是一种可接受的方法。根据您的具体要求,有多种方法可以做到这一点。一种方法是使用 Property 方法,如下所示:
var salesMethod = context.SaleMethods.Find(2); // Basically equivalent to your query
context.Entry(salesMethod).Property(e => e.Name).CurrentValue = newName;
context.Entry(salesMethod).Property(e => e.SomeOtherProp).CurrentValue = newOtherValue;
context.SaveChanges();

这些博客文章包含一些可能有用的附加信息:

http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx

http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx

关于asp.net-mvc-3 - Entity Framework 代码优先 : "The ObjectStateManager cannot track multiple objects with the same key.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9611003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com