【问题标题】:Owin disposes IdentityDbContext before initializing ControllerOwin 在初始化 Controller 之前处理 IdentityDbContext
【发布时间】:2023-04-03 20:53:01
【问题描述】:

我刚刚将我的项目迁移到 Owin,并且对它的架构不太熟悉。 在此之前,我有一个 dbContext,我在 Controller 构造函数中对其进行了初始化。 迁移到 Owin 后,我从 IdentityDbContext 继承了我的 dbcontext。

我从构造函数中删除了它的初始化并创建了一个控制器属性(我希望在这里我可以在当前请求的生命周期内从 owin 存储库中检索上下文并继续在我的项目中使用它):

 public MyController()
{
 private static MyDataContext _myContext ;
    public MyDataContextMyContext
    {
        get
        {
            return _myContext ??
                   (_myContext = System.Web.HttpContext.Current.GetOwinContext().Get<MyDataContext>());
        }
    }}}

这里需要静态字段,我在 MyDataContext 中初始化它:

public class MyDataContext : IdentityDbContext
    {
    public static MyDataContext Create()
        {
            return new MyDataContext();
        } }

在 Startup.cs 我有这个:

 app.CreatePerOwinContext<MyDataContext>(MyDataContext.Create);
 app.CreatePerOwinContext<MyUserManager>(MyUserManager.Create);
 app.CreatePerOwinContext<MySignInManager>(MySignInManager.Create);

在我的基本控制器中,我有这个构造函数:

    public MyController()
    {

        if (MyContext.Database.Exists())
        {/.../}

'If' 行抛出异常:

System.InvalidOperationException:操作无法完成 因为 DbContext 已经被释放了。

当然,在 dbcontext 中覆盖 dispose 会有所帮助(仅用于测试),但显然这是错误的方法。

我最初的目标是在请求处于活动状态时对每个请求使用相同的上下文。我不想在控制器内创建一个新的数据库上下文(如果之前已经创建了一个数据库上下文,我为什么要这样做?)您能否建议一种将 mvc5 身份验证与 EF 数据上下文一起使用的最佳实践?

【问题讨论】:

  • 我建议您为每个请求设置一个上下文,这是在一个事务中控制真正更改/添加/删除和保存的唯一方法(当您调用 dbContext.SaveChanges() 或 dbContext.Commit() 时。跨度>
  • 嗨,但这正是我想要实现的目标,但是,当我尝试检索上下文时,由于某种原因它已经被处理了。

标签: c# entity-framework asp.net-mvc-5 owin


【解决方案1】:

只需删除 static 关键字...控制器类必须根据请求进行实例化,将上下文存储在静态变量中,在调用之间共享它。

【讨论】:

  • 我说的是“私有静态 MyDataContext _myContext ;”这只是控制器中的一个字段,绝不是 owin 规范的一部分,用于访问此字段的 getter 是为了可测试性而制作的,您可以在测试中注入上下文...
  • 谢谢!我的错,我真的不知道为什么我将此私有字段标记为静态。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多