Use DbContext in ASP .Net Singleton Injected Class
我需要在一个在我的startup类中实例化的singleton类中访问我的数据库。似乎注入它会直接导致释放的dbContext。
我得到以下错误:
Cannot access a disposed object. Object name: 'MyDbContext'.
我的问题是双重的:为什么这不起作用,我如何在单例类实例中访问我的数据库?
以下是我的启动类中的configureServices方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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>(); } |
这是我的控制器类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class TestController : Controller { private FunClass _fun; public TestController(FunClass fun) { _fun = fun; } public List<string> Index() { return _fun.GetUsers(); } } |
这是我的funclass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } } |
它不起作用的原因是
如果你真的需要在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } } |
这就是说,我的建议是仔细考虑一下你是否真的需要你的娱乐班成为单身,除非你有一个很好的理由让它成为单身。
解决方案是调用addsingleton,在我的startup类的方法参数中实例化我的类:
1 |
解决方案是更改我的dbContext类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class MyContext : IdentityDbContext<ApplicationUser> { private string connectionString; public MyContext() { } public MyContext(DbContextOptions options, string connectionString) { this.connectionString = connectionString; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // Used when instantiating db context outside IoC if (connectionString != null) { var config = connectionString; optionsBuilder.UseSqlServer(config); } base.OnConfiguring(optionsBuilder); } } |
然而,正如多位人士警告的那样,在单例类中使用dbContext可能是一个非常糟糕的主意。我在实际代码中的用法非常有限(不是示例funclass),但我认为如果您这样做,最好找到其他方法。
如前所述,
您必须自己创建和释放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class FunClass { private DbContextOptions<MyDbContext> _dbContextOptions; public FunClass(DbContextOptions<MyDbContext> dbContextOptions) { _dbContextOptions = dbContextOptions; } public List<string> GetUsers() { using (var db = new MyDbContext(_dbContextOptions)) { return db.Users.Select(c=>c.UserName).ToList(); } } } |
在
1 2 3 4 |
有点脏,但效果很好。
不需要重载mydbContext的ctor。
1 |