c# - 手动实例化多个 DbContext 无需依赖注入
问题描述
我想创建一个 ASP.Net Core Web 服务,它将从一个 SQL Server 数据库中选择行并将它们插入到 X SQL Server 数据库中。所有数据库都具有相同的结构(相同的模型)。
我不想注入 DbContext,因为我不知道必须使用多少上下文并且很难维护。
是否可以在控制器或管理器中手动创建 DbContext,例如:
MyContextClass dbContext = new MyContextClass("myConnectionString");
谢谢
解决方案
是的,可以只创建一个新的DbContext
. 但是,在使用 DI 时,您应该编写和注入类似于DbContextFactory
类的东西,您可以使用它来创建新的上下文,并且它本身可以DbContextOptions
从您的配置中获取。
public class ContextFactory<TContext>
where TContext : DbContext
{
private readonly Func<TContext> _createContext;
public ContextFactory(Func<TContext> createContext)
{
_createContext = createContext ?? throw new ArgumentNullException(nameof(createContext));
}
TContext CreateForRead()
{
var context = Create();
context.ChangeTracker.AutoDetectChangesEnabled = false;
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
return context;
}
TContext CreateForWrite() => Create();
private TContext Create()
{
var context = _createContext();
if (context == null)
throw new NullReferenceException($"{nameof(_createContext)} must not return null.");
return context;
}
}
为了更方便使用,创建一个扩展类:
public static class ServiceCollectionDataExtensions
{
public static void AddDatabase<TDbContext>(this IServiceCollection services, string connectionString)
where TDbContext : DbContext
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentNullException(nameof(connectionString));
services.AddDbContext<TDbContext>(c => c.UseSqlServer(connectionString), ServiceLifetime.Transient);
services.AddScoped(provider => new ContextFactory<TDbContext>(() => ActivatorUtilities.CreateInstance<TDbContext>(provider, provider.GetRequiredService<DbContextOptions<TDbContext>>())));
}
}
然后在您public void ConfigureServices(IServiceCollection services)
的配置中添加连接字符串:
services.AddDatabase<MyDbContext>(Configuration.GetConnectionString("MyDatabase"));
推荐阅读
- docker - Docker 容器在挂载中收到权限被拒绝
- meteor - 用于传递变量的 GraphQL 查询参数语法
- debugging - fmt.Scanln 的调试问题
- python - Boto 出口安全策略
- haskell - Haskell 中的编码和高效 IO
- sql - 数据库设计中的项目编辑请求
- json - 如何在 Oracle 中将 JSON 字符串转换为 JSON
- python - Cplex(Python),model.solution给出的结果与model.print_solution()不同是否正常?
- javascript - 未捕获的类型错误:无法在 resumeVideo 处读取 null 的属性“播放”
- javascript - 如何管理 Cordova FileTransfer 错误上的空返回码?