c# - 如何配置 EF Core 连接上下文以解耦包依赖关系?
问题描述
我使用 Entity Framework Core 创建了一个库来处理持久性。它由针对 SQL Server 数据库的 Web API 使用。此外,我针对 SQLite 数据库对其进行了测试(单元测试)。
我使用配置文件以简单的方式完成了它。因此,在我扩展 DBContext 的类中,我使用以下代码实现了 OnConfiguring:
if(isSqlServer) //don't mind where it comes from, it works fine
optionsBuilder.UseSqlServer(connectionString);
else
optionsBuilder.UseSqlite(connectionString);
它似乎工作正常,但它有一个不希望的效果。假设我有这个项目:
- 持久层
- 持久层测试
- 网络API
由于方法 UseSqlite 是包 Microsoft.EntityFrameworkCore.Sqlite 的类中的静态扩展方法,同样,方法 UseSqlServer 是包 Microsoft.EntityFrameworkCore.SqlServer 的类中的静态扩展方法,有两件事困扰我。
首先,我必须在三个项目中包含这两个依赖项,以避免在运行时出现错误“System.IO.FileNotFoundException:无法加载文件或程序集 Microsoft.EntityFrameworkCore.SqlServer (...)”。
其次,如果我需要支持新的 DBMS(Oracle、MySQL),我必须在这三个项目上包含新的依赖项。
我希望构建一个 PersistentLayer 项目没有这些依赖项的场景,而 PersistentLayerTests 将仅依赖于 Microsoft.EntityFrameworkCore.Sqlite,而 WebAPI 将仅依赖于 Microsoft.EntityFrameworkCore.SqlServer。
是否有另一种方法来配置连接上下文以解耦这些包依赖关系?
笔记:
- 我使用 NHibernate 做到了这一点,它为每个 DBMS 使用不同的驱动程序实现。
- 我尝试使用反射,但并不优雅,而且我注意到如果扩展方法具有不同的参数,它将无法工作。
- 我不需要完整的解决方案。如果有人能以另一种方式指出我,那将非常有帮助。
解决方案
您只需让 DbContext 的用户(PersistenceLayerTests 和 WebApi 项目)负责配置它,而不是DbContext本身。
DbContext 提供了一个接受DbContextOptions的构造函数。您需要公开此构造函数:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
// ...
}
然后,这使您能够执行以下操作:
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
if (isSqlServer) //don't mind where it comes from, it works fine
optionsBuilder.UseSqlServer(connectionString);
else
optionsBuilder.UseSqlite(connectionString);
using (var context = new MyDbContext(optionsBuilder.Options))
{
// ...
}
推荐阅读
- r - 在 R 中,您如何估算低于检测限的左删失数据?
- authentication - 气流反向代理和 DAG 隔离
- c - 使用带有结构的指针 - 不读取正确的地址
- ruby-on-rails - 将数组传递给 rails button_tag
- python - 如何根据一列中的值范围替换(编码)多个值?
- c# - 如何绑定列表
值是作为(SyncFusion)DropDownList的DataSource的“一些”对象的列表? - swift - 使用多部分表单数据上传多个图像(带参数) - Alamofire 5
- python - 从基本代码导入 xgboost 出错
- laravel - laravel 中用于订单信息的自定义中间件
- javascript - 为班级制作风格并为其他人删除