如何设置和配置实体框架核心以使用单个DbContext
类并管理多个提供程序(SQL Server、Sqlite)的迁移?
我正在生产一个.NET6Blazor WASM项目,它托管在ASP.NETWeb API中,使用C#项目(客户端、API、逻辑、数据和共享项目)的标准体系结构。DbContext
被注入到存储库中,然后在逻辑层中使用。一旦请求完成,服务和DbContext
就会被释放。一切都很好。
我想创建一个配套的桌面应用程序(WinUi3),它使用相同的逻辑层和数据层,但使用SQLite数据提供程序。我可以使用从现有DbContext
继承的新DbContext
类,但是存储库不知道使用哪个DbContext
。
文档(针对多个提供程序和单个上下文)没有为SQLite提供程序提供新的ModelSnapshot
。因此,为update-database
生成的SQL代码仍然使用SQL Server的语法编写。
架构和配置:
Data.Migrations.csproj
(项目仅用于迁移,如here所示):
- 迁移(用于SQL Server提供程序的文件夹)
- Migrations/Sqlite(SQLite提供程序的文件夹)
Data.csproj
(包含DbContext
和存储库的项目):
public class Context : DbContext
{
protected readonly IConfiguration Configuration;
public Context() { }
public Context(DbContextOptions<Context> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// some model configuration
}
// DbSets...
}
public interface IRepository<T> where T : class
{
// some interface methods
}
public class Repository<T> : IRepository<T> where T : class
{
private DbSet<T> entities;
public Repository()
{
}
// implement some interface methods
}
public class DbContextFactory : IDesignTimeDbContextFactory<Context>
{
public Context CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<Context>();
if (DbContextHelper.Provider == "SqlServer")
optionsBuilder.UseSqlServer(DbContextHelper.ConnectionString,
x => x.MigrationsAssembly("Data.Migrations"));
else if (DbContextHelper.Provider == "Sqlite")
optionsBuilder.UseSqlite(DbContextHelper.ConnectionString,
x => x.MigrationsAssembly("Data.Migrations"));
else
throw new InvalidOperationException("Database provider not specified");
return new Context(optionsBuilder.Options);
}
}
Logic.csproj
:
public interface ICustomerService
{
// some interface methods
}
public class CustomerService : ICustomerService
{
protected readonly IRepository<Customer> _customerRepository;
public CustomerService(IRepository<Customer> customerRepository)
{
_customerRepository = customerRepository;
}
// implement some interface methods
}
Api.csproj
:
// Program class
builder.Services.AddDbContext<Context>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Context"),
x => x.MigrationsAssembly("Data.Migrations"))
);
builder.Services.AddTransient<ICustomerService, CustomerService>();
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
builder.Services.AddScoped<DbContext, Context>();
WinUi.csproj
(WinUi 3 app~=UWP app):
// App.xaml.cs
public App()
{
services.AddDbContext<InSpecContext, Context>(options =>
options.UseSqlite(DbContextHelper.ConnectionString,
x => x.MigrationsAssembly("Data.Migrations"))
);
}
1条答案
按热度按时间s71maibg1#
我最终摆脱了@PanagiotisKanavos发表的现已删除的评论所建议的存储库模式。
然后,我使用位于
Data
项目中的DbContext文件为我的每个提供程序创建了一个单独的迁移项目。然后,在
Logic
服务中,我不是注入泛型存储库或DbContext,而是按照这里的建议注入IDbContextFactory<MyContext> factory
API的配置如下所示
WinUi应用的配置如下所示: