我在ASP.NET MVC应用程序中使用.NET 3.5 SP1。
在使用具有Http Request生命周期的ObjectContext并尝试附加上下文中存在的实体ALREADY时,我们收到错误: “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 Request生命周期的ObjectContext时附加实体的更多问题。
例如,如果我们有“AppUser”,“类别”和部门实体。
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)) {
仅在上下文中起作用
一个选项是通过始终使用NOMERGE NoTracking选项检索来确保上下文没有附加实体。但我发现MergeOption.NoTracking存在以下问题:
请告知。
谢谢。
答案 0 :(得分:0)
您的代码使用两种不同的上下文。你检查一个,然后附加到另一个:
if( csContext. //...){
///
}else{
ctx. // ...
}
该实体似乎位于ctx
,但不在csContext
。我的建议是尽可能一次只使用一个上下文;它不那么令人困惑。
<强>更新强>
好的,你已经改变了问题中的代码。
我的猜测是你的存根对象没有EntityKey,所以TryGetObjectStateEntry返回false。尝试:
if( ctx.ObjectStateManager.TryGetObjectStateEntry(
new EntityKey("MyEntities.CategorySet", "CategoryId", CategoryIdSelected),
out stateEntry)){
显然,将“MyEntities”替换为实际的型号名称。