如何在静态类中使用dbcontext?(的ObjectDisposedException)

J.K*_*rk. 4 c# extension-methods entity-framework dbcontext asp.net-core-2.0

嘿,我刚刚学会了如何使用扩展方法,并非常兴奋地在我当前的项目中实现它.

我的目标: 我想检查我的表中是否存在辅助类中的条目,因为我将在多个控制器中使用它以确定在我的导航栏中显示哪些导航链接:在此输入图像描述

我的问题: 我不知道如何在我的静态助手类中访问我的dbcontext.我的dbcontext控制器接受一个参数,我不知道如何传递我的静态类.我认为创建一个新的dbcontext将解决我在下面解释的范围问题,但我没有看到我如何将option参数传递给我的构造函数.

在此输入图像描述

它当前在Startup.cs类中配置. 在此输入图像描述

我尝试了什么: 将ApplicationDbContext作为参数传递.这适用于我的控制器中的单个方法调用,但是当调用多个扩展方法时(为了检查用户具有哪些游戏帐户),我得到一个ObjectDisposedException.

ObjectDisposedException:无法访问已处置的对象.此错误的常见原因是处理从依赖项注入解析的上下文,然后尝试在应用程序的其他位置使用相同的上下文实例.如果您在上下文中调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况.如果使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例.对象名:'ApplicationDbContext'.

根据我的理解,这是一个范围问题,第一个方法调用在完成时处理上下文,我试图在下一次调用中使用相同的上下文?我该怎么做才能解决这个问题?

我尝试阅读此链接注入DbContext时无法访问ASP.NET Core中的已处置对象,但它对我没有帮助,因为它需要Startup.cs类中的ApplicationBuilder.

在此输入图像描述

解决方案更新 我在每个方法调用之后都放置了dbcontext,因为我将它放入一个变量中.相反,我直接在传递的上下文上调用它,它可以工作:

在此输入图像描述

Chr*_*att 6

是的,所以,虽然扩展对你来说是新的和有光泽的,但这并不意味着你应该将它们用于一切.首先,扩展应该与它们正在操作的类型建立逻辑连接.例如,如果你有一个string类似于ToUpper()扩展的东西,因为它修改并返回一个字符串.你正在尝试做的事情:只使用引用的值来返回完全外来类型是违反扩展模式的.

其次,扩展不应与数据库之类的东西进行交互.特别是在这里,扩展的静态性质与EF上下文对象的概念完全不兼容.你甚至可以让它工作的唯一方法是每次在扩展中调用扩展时实际上新建一个上下文.这既是搞砸EF对象跟踪内容的好方法,也是泄漏内存的好方法.

多空,不要这样做.

如果您只是想要分解这些代码,那么您有更好的选择.例如,您实际上可以直接将方法添加到您的上下文中.

public class ApplicationDbContext : DbContext
{
    ...

    public bool HasDota2Account(string id)
    {
        return Dota2Accounts.Any(m => m.ApplicationUserId == id);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的控制器中,您可以简单地执行:

var hasDota2Account = context.HasDota2Account(User.Identity.GetUserId());
Run Code Online (Sandbox Code Playgroud)