在ASP .Net Singleton注入类中使用DbContext [英] Use DbContext in ASP .Net Singleton Injected Class

查看:247
本文介绍了在ASP .Net Singleton注入类中使用DbContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Startup类中实例化的Singleton类中访问数据库.似乎直接注入它会导致DbContext被处置.

I need to access my database in a Singleton class instantiated in my Startup class. It seems that injecting it directly results in a DbContext that is disposed.

我收到以下错误:

无法访问已处置的对象.对象名称:"MyDbContext".

Cannot access a disposed object. Object name: 'MyDbContext'.

我的问题有两个:为什么不起作用,如何在单例类实例中访问数据库?

My question is twofold: Why doesn't this work and how can I access my database in a singleton class instance?

这是我的Startup类中的ConfigureServices方法:

Here is my ConfigureServices method in my Startup class:

public void ConfigureServices(IServiceCollection services)
{
    // code removed for brevity

    services.AddEntityFramework().AddSqlServer().AddDbContext<MyDbContext>(
        options =>
        {
            var config = Configuration["Data:DefaultConnection:ConnectionString"];
            options.UseSqlServer(config);
        });

    // code removed for brevity

    services.AddSingleton<FunClass>();
}

这是我的控制器类:

public class TestController : Controller
{
    private FunClass _fun;

    public TestController(FunClass fun)
    {
        _fun = fun;
    }

    public List<string> Index()
    {
        return _fun.GetUsers();
    }
}

这是我的FunClass:

Here is my FunClass:

public class FunClass
{
    private MyDbContext db;

    public FunClass(MyDbContext ctx) {
        db = ctx;
    }

    public List<string> GetUsers()
    {
         var lst = db.Users.Select(c=>c.UserName).ToList();
        return lst;
    }
}

推荐答案

之所以不起作用,是因为.AddDbContext扩展将其添加为每个请求的作用域.通常,每个请求都是您希望的范围,通常每个请求将调用一次保存更改,然后将dbcontext放置在请求的末尾.

The reason it doesn't work is because the .AddDbContext extension is adding it as scoped per request. Scoped per request is generally what you want and typically save changes would be called once per request and then the dbcontext would be disposed at the end of the request.

如果您确实需要在singleton中使用dbContext,那么您的FunClass类可能应该依赖于IServiceProviderDbContextOptions,而不是直接依赖于DbContext,这样您就可以自己创建它.

If you really need to use a dbContext inside a singleton, then your FunClass class should probably take a dependency on IServiceProvider and DbContextOptions instead of directly taking a dependency on the DbContext, that way you can create it yourself.

public class FunClass
{
    private GMBaseContext db;

    public FunClass(IServiceProvider services, DbContextOptions dbOptions) 
    {
        db = new GMBaseContext(services, dbOptions);
    }

    public List<string> GetUsers()
    {
         var lst = db.Users.Select(c=>c.UserName).ToList();
        return lst;
    }
}

也就是说,我的建议是仔细考虑您是否真的需要FunClass成为单身人士,除非您有充分的理由使其成为单身人士,否则我会避免这种情况.

That said, my advice would be to carefully consider whether you really need your FunClass to be a singleton, I would avoid that unless you have a very good reason for making it a singleton.

这篇关于在ASP .Net Singleton注入类中使用DbContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆