【发布时间】:2011-09-08 02:27:39
【问题描述】:
我在 ASP.NET MVC 应用程序中使用 .NET 3.5 SP1。
在使用带有 Http 请求生命周期的 ObjectContext 并尝试附加一个已经存在于上下文中的实体时,我们收到错误: “ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。” 例如代码:
Category newCategory = new Category {CategoryId = CategoryIdSelected};
ctx.AttachTo("CategorySet", newCategory);
如果 ObjectContext 中存在 CategoryId = CategoryIdSelected 的 'Category' 会出错。
修改代码以检查现有实体:
Category newCategory = new Category {CategoryId = CategoryIdSelected};
ObjectStateEntry stateEntry = null;
if( ctx.ObjectStateManager.TryGetObjectStateEntry(newCategory, out stateEntry)){
//EntityObject already attached in context, get it
newCategory = (EntityObject)stateEntry.Entity;
}else{
ctx.AttachTo("CategorySet", newCategory);
}
修改后的代码仍然报同样的错误: "[System.InvalidOperationException] = {"ObjectStateManager 中已经存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同键的多个对象。”
请指教?
谢谢
问题附录:
在使用具有 Http 请求生命周期的 ObjectContext 时附加实体的更多问题。
例如,如果我们有 'AppUser'、'Category' 和 Department 实体。
public class AppUser : System.Data.Objects.DataClasses.EntityObject{
public int Uid {get; set;}
public string UserName {get; set;}
public string Password {get; set;}
public Department Dept {get; set;}
public Category catg {get; set;}
...........
}
AppUser 与部门和类别实体有关系。 现在尝试附加“用户”时:
user = new AppUser{Uid=1,catg = new Category {categoryId=10}, Dept = new Department{departmentId=101}, ...}
var key = ctx.CreateEntityKey("AppUserSet", user);
if (ctx.ObjectStateManager.TryGetObjectStateEntry(key, out stateEntry)) {
只有在上下文中才会起作用:
- 没有 categoryId=10 的类别,并且
- 没有 DepartmentId=101 的部门
一个选项是通过始终使用 NOMERGE NoTracking 选项进行检索来确保上下文没有附加实体。但我发现 MergeOption.NoTracking 存在以下问题:
- 第二次调用仍会导致数据库命中
- 您没有在 EntityRefs 上获得 EntityKeys。所以 XXXReference 的 EntityKey 为空,这意味着没有 FK Stub。 Please see.
如何在不加载两端(两个实体)的情况下获取引用的 EntityKey? - 即使实体已分离,它们也有对 DataContext 的引用(通过 entity._realtionships._context)。 Please see.
请指教。
谢谢。
【问题讨论】:
标签: entity-framework