我正在使用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的其他配置。如何实现?
答案 0 :(得分:7)
除了使用它的可争议的好处(来自文档:“具有节省DbContext实例初始化成本的优点” ),DbContext pooling根本不适用在您的方案中,因为您的上下文包含EF Core不知道的 state :
private readonly DatabaseSettings _databaseOptions;
和文档的Limitations部分明确指出:
警告!
如果在派生的DbContext类中维护自己的状态(例如,私有字段),则不应使用DbContext池,不应在请求之间共享该状态。 EF Core只会在将DbContext实例添加到池中之前重置知道的状态。
有一个理由要求optionsAction
中的AddDbContextPool
,而对于AddDbContext
是可选的。这是由于上述限制,加上额外的要求,即您的DbContext
派生类必须具有带有 single DbContextOptions
参数的 single 公共构造函数。您可以通过传递空操作来愚弄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
必须在外部配置。
换句话说,您的要求是相互排斥的,因此没有解决方案。