c# - 如果 DbContext 的 OnConfiguring 方法中的所有配置,如何使用 AddDbContextPool
问题描述
我正在使用 PostgreSQL,我有 ApplicationDbContext 像:
public class ApplicationDbContext : DbContext
{
private readonly DatabaseSettings _databaseOptions;
public ApplicationDbContext() { }
public ApplicationDbContext(IOptions<DatabaseSettings> databaseOptions)
{
_databaseOptions = databaseOptions.Value;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasPostgresExtension("citext");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (_databaseOptions == null)
{
optionsBuilder.UseInMemoryDatabase(Guid.NewGuid().ToString());
}
else
{
optionsBuilder.UseNpgsql(_databaseOptions.ConnectionString,
npgsqlOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: _databaseOptions.MaxRetryCount,
maxRetryDelay: TimeSpan.FromSeconds(_databaseOptions.MaxRetryDelay),
errorCodesToAdd: null);
});
}
}
}
这种背景是许多其他人的基础。我正在改进性能并尝试使用上下文池。文档说要添加投票,我应该:
services.AddDbContextPool<EmployeeContext>(options => options.UseNpgsql(connection));
但我想在 OnConfiguring 方法中存储.UseNpgsql 和 DbContext 的其他配置。如何做到这一点?
解决方案
除了使用它的有争议的好处(来自文档:“具有节省初始化 DbContext 实例的一些成本的优势”)之外,DbContext 池在您的场景中根本不适用,因为您的上下文包含EF Core 的状态不知道:
private readonly DatabaseSettings _databaseOptions;
并且文档的限制部分明确指出:
警告!
如果您在派生的 DbContext 类中维护自己的状态(例如,私有字段),不应在请求之间共享,请避免使用 DbContext 池。EF Core 只会重置在将 DbContext 实例添加到池之前知道的状态。
optionsAction
需要of是有原因的AddDbContextPool
,而 forAddDbContext
它是可选的。这是由于上述限制,以及DbContext
派生类必须具有单个公共构造函数和单个 DbContextOptions
参数的附加要求。AddDbContextPool
您可以通过传递空操作来轻松地看到这一点:
services.AddDbContextPool<ApplicationDbContext>(options => { });
但是在运行时你会InvalidOperationException
说
'ApplicationDbContext' 类型的 DbContext 不能被池化,因为它没有一个接受 DbContextOptions 类型的单个参数的公共构造函数。
所以为了有资格获得池,你必须删除所有这些
private readonly DatabaseSettings _databaseOptions;
public ApplicationDbContext() { }
public ApplicationDbContext(IOptions<DatabaseSettings> databaseOptions)
{
_databaseOptions = databaseOptions.Value;
}
并添加这个
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
现在您应该清楚地看到为什么您所要求的内容是不可能的。您的OnConfiguring
方法需要DatabaseSettings
,但您无法提供它。因此options
必须在外部进行配置。
换句话说,您的要求是相互排斥的,因此没有解决方案。
推荐阅读
- docker - Docker-compose filebeat连接问题到logstash
- sql - 运行时错误 3061 预期参数太少 4
- javascript - Storybook 调用函数,它是组件的一个 prop
- python - 如何在 Python 中将具有随机名称的文件从一个文件夹移动到另一个文件夹?
- sql - 使用 SQL 将输入表转换为提到的输出表
- reactjs - React with redux 管理状态表单数据输入字段
- c# - DLL 中的类
- angular - 智能表 Angular 2 验证
- angular - Angular 5 亲子沟通
- javascript - 使用角度向现有类添加样式