【问题标题】:Updating entity stored outside current DbContext更新存储在当前 DbContext 之外的实体
【发布时间】:2013-12-26 21:59:16
【问题描述】:

在实体框架中处理以下场景的推荐方法是什么?

我有一些与会话相关的数据存储在一个名为SessionData 的类中(它使用单例模式)。此类中的属性之一称为Basket。 Basket 类有一个BasketItems 的集合。

所以当篮子初始化时,它会被添加到数据库并存储在会话中:

var basket = new Basket();

using(var db = new DataContext())
{
    db.Baskets.Add(basket);
    db.SaveChanges();
}

SessionData.Current.Basket = basket;

然后当一个购物篮项目被添加到购物篮时:

using(var db = new DataContext())
{
    var basketItem = new BasketItem() { initialisation here }
    SessionData.Current.Basket.BasketItems.Add(basketItem);
    db.SaveChanges();
}

这不起作用,因为SessionData.Current.Basket 未附加到当前 DbContext。我试过使用:

db.Baskets.Attach(SessionData.Current.Basket)

这在第一次调用时有效,但在以下调用时失败并出现以下错误:

ObjectStateManager 中已存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同键的多个对象。

对存储在当前 DbContext using 块之外的实体(及其层次结构)进行此更新的推荐方法是什么?

【问题讨论】:

  • 为什么SessionContext 有上下文? (或者,为什么它是一个EF上下文?)。
  • @GertArnold 抱歉,我可能将这个问题与我的 SessionContext 类的名称混淆了。这与 DbContext 或 EF 无关。我现在将更新我的问题以消除这种混乱。
  • @DanielAuger 谢谢,今晚稍后会看看那个帖子。
  • @DanielAuger 感谢您的链接 - 答案中的链接很有帮助。我不认为这是一个重复的问题,因为问题并不完全相同。它确实帮助我解决了我的问题。

标签: c# entity-framework entity-framework-6


【解决方案1】:

在新的数据库上下文中,从数据库中检索购物篮,然后创建新的购物篮项目。

【讨论】:

  • 这听起来有点低效,因为我已经在内存中有购物篮信息。
  • 啊,但你在 EF 中没有它的实体。我有兴趣看到最终的解决方案。
【解决方案2】:

问题原来是因为当我初始化新 BasketItem 的属性时,它的一个属性(称为Product)被另一个 DbContext 实例跟踪。我没有发现它,因为我正在考虑 Basket 类,而不是它的子属性。我通过更改从中获取产品实例的查询来解决这个问题:

var product = (from x in db.Products
               where x.ID == basketRequest.ProductID
               select x).FirstOrDefault();

到:

var product = (from x in db.Products.AsNoTracking()
               where x.ID == basketRequest.ProductID
               select x).FirstOrDefault();

获取实体实例而不被 DbContext 跟踪。

question Daniel Auger 在他的评论中提到的The link 也帮助我理解了“插入或更新模式”,这正是我的问题所在。我不同意这两个问题是重复的,因为它们并不完全相同。不过非常有用的链接!

【讨论】:

    猜你喜欢
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 2019-09-20
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    相关资源
    最近更新 更多