【发布时间】:2019-09-16 10:52:46
【问题描述】:
我有一种情况,我需要在我的解决方案启动后实例化我的 DBContext。我问过这个question,这表明我可以用constructor argument 做到这一点。
有人建议我作为一个例子来实现:
var connection = @"Server=(localdb)\mssqllocaldb;Database=JobsLedgerDB;Trusted_Connection=True;ConnectRetryCount=0";
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlServer(connection);
using (var context = new BloggingContext(optionsBuilder.Options))
{
// do stuff
}
但是,我已经实现了存储库模式(无论好坏)并考虑到我的变化情况 - 在解决方案运行启动之前没有连接字符串 - 我需要将它实现到基础存储库类中,我处于有点亏。。
目前我有这个:
public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntityBase, new()
{
public JobsLedgerAPIContext _context;
#region Properties
public EntityBaseRepository(JobsLedgerAPIContext context)
{
_context = context;
}
#endregion
public virtual IQueryable<T> GetAll()
{
return _context.Set<T>().AsQueryable();
}
public virtual int Count()
{
return _context.Set<T>().Count();
}
......
如何在构造函数中实例化 DBContext(通过绕过在启动时将上下文添加为服务的需要)以及使用“使用”等包装每个虚拟方法来实现此更改
EDIT.. Camilo 表示我没有确定我何时拥有数据库名称。
基本情况是系统启动(这是一个Aurelia SPA项目,与此问题无关)将包发送到显示登录屏幕的浏览器。用户登录.. 用户通过 JWT 控制器进行验证.. 一旦在控制器中验证(使用一个目录数据库,该数据库有一个包含 3 个字段的表 - 用户名、密码、数据库名称),我使用数据库名称创建一个连接字符串和然后在那时实例化我的 DBContext.. 所以通过构造函数。
下面的答案需要修改,因为带有工厂答案(有希望)的答案有这个question发现的错误。Nkosi 对错误给出了很好的答案。
编辑 2.. 这是对以下已编辑问题的回复:
这是我的原始客户端存储库,构造函数上有 :base(context)。
using JobsLedger.DATA.Abstract;
using JobsLedger.MODEL.Entities;
namespace JobsLedger.DATA.Repositories
{
public class ClientRepository : EntityBaseRepository<Client>, IClientRepository
{
private new JobsLedgerAPIContext _context;
public ClientRepository(JobsLedgerAPIContext context) : base(context)
{
_context = context;
}
public void RelatedSuburbEntities(Suburb _suburb)
{
_context.Entry(_suburb).Reference<State>(a => a.State).Load();
}
}
}
它引用了基类“上下文”。我不确定如何修改它,因为我相信我最后仍然需要“:base(context)”。同样,我有一个方法可以访问 _context 以及它是构造函数的一部分......
此外,我假设我不能再将服务注入控制器,而是在确保连接字符串安全后将其重新启动,然后将该连接字符串传递给服务。
另外,鉴于我现在在启动时添加了一个单例,我需要删除原始条目吗? :
services.AddDbContext<JobsLedgerAPIContext>(options => options.
UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("JobsLedger.API")));
有效地将其替换为我的单例参考,如下所示:
services.AddSingleton(typeof(IContextFactory), typeof(ContextFactory));
【问题讨论】:
-
“在解决方案运行启动之前没有连接字符串”但是你什么时候有连接字符串?用户给你连接字符串了吗?
标签: c# asp.net-core dependency-injection entity-framework-core