背景
我在更新EF中的实体时遇到了一些麻烦。我一直收到这个错误:
“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象”
我完全清楚,显然有一个附加的实体。但是,我目前无法追踪它。有很多代码,我已经花了很多时间在它上面。据我所知,我在所有查询中都使用了AsNoTracking()
扩展方法。
我需要什么
我的问题是:在任何给定时间,我有什么方法可以看到 ObjectStateManager 中的实际内容?如果我在调试期间可以看到那里的项目,我可以更快地找到它的来源。
如果以上情况不可能,我会很感激如何最好地解决这个问题......就像现在大海捞针一样。
答案 0 :(得分:3)
有什么办法可以在任何给定时间看到ObjectStateManager中的实际内容吗?如果我在调试期间可以看到那里的项目,我可以更快地找到它的来源。
您还可以使用Visual Studio调试器的Quick Watch功能查看ObjectStateManager中的内容。路径是:
上下文 - > ObjectContext - > ObjectStateManager - >非公开成员
答案 1 :(得分:1)
这个问题有帮助:
what is the most reasonable way to find out if entity is attached to dbContext or not?
我以这种方式实现了它:
var attachedEntity = context.ChangeTracker.Entries<T>().FirstOrDefault(x => x.Entity.Id == entity.Id);
// If the entity is already attached.
if (attachedEntity != null)
{
// Set new values
attachedEntity.CurrentValues.SetValues(entity);
}
else
{
// Else attach the entity (if needed)
if (context.Entry(entity).State == EntityState.Detached)
{
Entities.Attach(entity);
}
// Set the entity's state to modified
context.Entry(entity).State = EntityState.Modified;
}
context.SaveChanges();
注意:Entities
只是来自IDbSet<T>
的{{1}},上面的代码来自我的通用存储库中的Update()方法。
答案 2 :(得分:1)
经常被忽视:Context.Set<T>.Local()
,它为相关类型提供了仅附加的实体。
答案 3 :(得分:0)
这篇文章:http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/08/27/9656.aspx包含一些用于转储ObjectStateManager
内容的代码。
来自here:
这里发生的事情几乎肯定是你的对象 尝试删除不是附加,而是相关的实体或集合 加载在分离的实例上已经附加到了 ObjectContext的。因此,当您尝试附加您尝试的实体时 删除,我们尝试附加整个图,其中包括实体 已经附上了。
这类问题有点痛苦,所以在我的情况下,我尽量在单个using(Context context = new MyEntities())
区块中尽可能多地进行活动。
另一条建议是在添加对象之前检查对象是否已存在。有点显而易见,我知道,但我过去几次被那个人绊倒了。