【问题标题】:EF: Update entity stored in sessionEF:更新存储在会话中的实体
【发布时间】:2012-10-02 20:58:32
【问题描述】:

我将 EF 5 与 Web 表单 (ASP.NET 4.5) 结合使用,采用“每个请求一个 DbContext 实例”的方法。

但是这种情况有点复杂:我有一个多步骤的创建/编辑屏幕,我将当前实体存储在 Session 中,然后我对其进行操作,在最后一步中,我将其提交到数据库。

创建一个新实例很好,但我无法终生编辑现有实体...因为这是另一个请求,我原来的 DbContext 实例丢失了,当我将它附加到一个新实例时,我得到了一个实体对象不能被多个IEntityChangeTracker实例引用错误。

我的代码过于复杂,无法在此处发布,但我会尝试准确地总结一下:

我的 DbContext:

public class AppContext : DbContext
{
    // DbSet declarations...

    public static AppContext Current { 
         get { var context = HttpContext.Current.Items["Contexts.AppContext"] as AppContext;
             if (context == null)
             {
                 context = new AppContext();
                 HttpContext.Current.Items["Contexts.AppContext"] = context;
             }
             return context; 
         }
    }
}

页面代码的示例:

protected void Page_Load(object sender, EventArgs e)
{
    int? id = null; // After this, I try to get it from the QueryString, parse it, etc.. Omitted for sake of brevity 

    // If I have an ID, it means I'm editing...
    Session["Product"] = id.HasValue ? new Product() : AppContext.Current.Products.Find(id));

    MethodToPopulateFields(); // Internally, it uses the Session variable
}

protected void Step1(){ // through n
    // Manipulates the Session["Product"] based on page input...
}

protected void Save(){
    var product = Session["Product"] as Product;

    if(product.ID == 0)
        product = AppContext.Current.Products.Add(product);

    // throws an exception:
    // AppContext.Current.Entry(product).State = EntityState.Modified;

    // this too:
    // AppContext.Products.Attach(product);

    AppContext.Current.SaveChanges();
}

我知道我可以从数据库中获取旧实体,手动更新并保存,所有这些都在最后一步,但我真的不想这样做......

谢谢。

【问题讨论】:

  • 仅供参考,为此使用会话是一种糟糕的方法。更好的解决方案是使用 MvcFutures 项目中的 @Html.Serialize 之类的东西将您的各个步骤序列化到每个连续步骤。这样您就不必担心并发问题(例如,如果用户在浏览器的两个不同选项卡中打开了两个版本的表单)。这也意味着如果用户起床去洗手间,他们不必担心当他们回来时会话会消失。
  • 我明白你的意思,但它是一个 Web 窗体应用程序,而不是 MVC。此外,它是一个旧版应用程序(我刚刚升级到 ASP.NET 4.5)......在这一点上很难改变它。
  • 在这种情况下,您有一个更好的选择,即 Asp.net 的 PreviousPage 属性,它使您可以访问以前的页面数据。这就是它的设计目的。

标签: asp.net entity-framework


【解决方案1】:

尝试调用

AppContext.Current.Entry(product).State = EntityState.Detached;

在第一种方法中。

【讨论】:

  • 我还没有测试它,因为我已经转移到应用程序的另一个问题上。我会在今天或明天回到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 2023-02-01
  • 2021-10-28
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
相关资源
最近更新 更多