我可以在调试时看到ObjectStateManager中的内容吗?

时间:2012-10-13 03:37:06

标签: c# entity-framework

背景

我在更新EF中的实体时遇到了一些麻烦。我一直收到这个错误:

“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象”

我完全清楚,显然有一个附加的实体。但是,我目前无法追踪它。有很多代码,我已经花了很多时间在它上面。据我所知,我在所有查询中都使用了AsNoTracking()扩展方法。

我需要什么

我的问题是:在任何给定时间,我有什么方法可以看到 ObjectStateManager 中的实际内容?如果我在调试期间可以看到那里的项目,我可以更快地找到它的来源。

如果以上情况不可能,我会很感激如何最好地解决这个问题......就像现在大海捞针一样。

4 个答案:

答案 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())区块中尽可能多地进行活动。

另一条建议是在添加对象之前检查对象是否已存在。有点显而易见,我知道,但我过去几次被那个人绊倒了。