在ASP .Net Singleton注入类中使用DbContext [英] Use DbContext in ASP .Net Singleton Injected Class
问题描述
我需要在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
类可能应该依赖于IServiceProvider
和DbContextOptions
,而不是直接依赖于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屋!