【问题标题】:Attaching Entities when using ObjectContext having lifetime of Http Request使用具有 Http 请求生命周期的 ObjectContext 时附加实体
【发布时间】: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


    【解决方案1】:

    您的代码使用了两种不同的上下文。您检查一个,然后附加到另一个:

    if( csContext. //...){
       ///
    }else{
        ctx. // ...
    }
    

    实体似乎在ctx 中,但不在csContext 中。我的建议是尽可能一次只使用一个上下文;它不那么令人困惑。

    更新

    好的,您已更改问题中的代码。

    我的猜测是您的存根对象没有 EntityKey,因此 TryGetObjectStateEntry 返回 false。试试:

    if( ctx.ObjectStateManager.TryGetObjectStateEntry(
        new EntityKey("MyEntities.CategorySet", "CategoryId", CategoryIdSelected), 
        out stateEntry)){
    

    显然,将“MyEntities”替换为实际模型名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多