Pr.*_*dor 5 c# entity-framework entity-framework-core ef-core-2.2
我正在使用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);
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种情况是许多其他情况的基础。我正在改善性能并尝试使用上下文池。文档说要添加轮询,我应该:
services.AddDbContextPool<EmployeeContext>(options => options.UseNpgsql(connection));
Run Code Online (Sandbox Code Playgroud)
但我想在OnConfiguring方法中存储.UseNpgsql和DbContext的其他配置。如何实现呢?
除了使用它的有争议的好处(从文档:“具有节约一定的DbContext实例的初始化成本的优势”),该的DbContext池根本就不是适用于您的情况,因为你的上下文包含状态这EF核心是不知道:
private readonly DatabaseSettings _databaseOptions;
Run Code Online (Sandbox Code Playgroud)
文档的“ 限制”部分明确指出:
警告!
如果在派生的DbContext类中维护自己的状态(例如,私有字段),则不应使用DbContext缓冲池,不应在请求之间共享该状态。EF Core只会在将DbContext实例添加到池中之前重置可识别的状态。
还有就是为什么有原因optionsAction的AddDbContextPool需要,而对于AddDbContext它是可选的。这是由于上述限制,加上额外的要求,即DbContext派生类必须具有带有单个参数的单个 public构造函数。您可以通过用传递的空动作来欺骗来轻松地看到这一点: DbContextOptionsAddDbContextPool
services.AddDbContextPool<ApplicationDbContext>(options => { });
Run Code Online (Sandbox Code Playgroud)
但是在运行时,您会InvalidOperationException说
无法合并类型为'ApplicationDbContext'的DbContext,因为它没有单个公共构造函数来接受类型为DbContextOptions的单个参数。
因此,为了有资格进行合并,您必须删除所有这些
private readonly DatabaseSettings _databaseOptions;
public ApplicationDbContext() { }
public ApplicationDbContext(IOptions<DatabaseSettings> databaseOptions)
{
_databaseOptions = databaseOptions.Value;
}
Run Code Online (Sandbox Code Playgroud)
并添加它
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
Run Code Online (Sandbox Code Playgroud)
现在,您应该清楚地知道为什么您的要求是不可能的。您的OnConfiguring方法需要DatabaseSettings,但您无法提供它。因此,options必须在外部进行配置。
换句话说,您的要求是相互排斥的,因此没有解决方案。