[英]EF Core 6/7 - Accessing derived DbContext
我有一个基础库,其中包含 DbContext class 中的一些基本实体(日志、设置等)。在我的特定项目中,我从这个 class 继承上下文并执行项目特定的操作。
基本上下文
public class BaseContext : DbContext {
public BaseContext(DbContextOptions<BaseContext> options)
: base(options)
{
}
}
项目特定上下文
public class ProjectContext: BaseContext {
public ProjectContext(DbContextOptions<BaseContext> options)
: base(options)
{
}
public ProjectContext(DbContextOptions options)
: base(options)
{
}
}
Startup中会添加上下文:
services.AddDbContext<Context>(options =>
{
if (Helpers.IsDevelopment())
{
options.EnableSensitiveDataLogging();
options.EnableDetailedErrors();
}
options.UseNpgsql(Configuration.GetConnectionString("Context"), b =>
{
b.MigrationsAssembly("App.Project.Specific");
b.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
b.EnableRetryOnFailure(5);
});
}
);
因此,在基础库中实现的一些服务和控制器与 BaseContext 一起工作,它是 Context 的子项。
public AssetsService(BaseContext db,...
因此,这会导致以下错误消息:
Unable to resolve service for type 'App.Shared.DataModel.BaseContext' while attempting to activate 'App.Shared.Services.AssetsService
那么如何正确地注入上下文以从两种方式获得访问权限呢?
DbContext 是一个多实体存储库和工作单元。 拥有“基础”存储库毫无意义,注册基础而不是具体存储库也毫无意义。
此外,当仅注册了一个基础 class 时,DI 容器无法自行猜测要创建哪个具体服务。 .NET 猜不到像AssetsService
或CustomersService
这样的具体的Repository 类想要的。 如果SalesContext
和MarketingContext
都继承自某个基础Context
class,为什么不将MarketingContext
发送到CustomersService
并将SalesContext
发送到WarehouseService
?
DI注册
对于初学者来说,所有将要使用的 DbContext 类型都需要注册。 如果服务需要 BaseContext,则应该注册 BaseContext。 与ProjectContext
、 TimeSheetContext
、 CustomerContext
等相同。注册基类 class 不会注册其派生类。
通用注册和配置
看来真正的问题是如何使用相同的代码注册多个 DbContext。 这可以通过接受DbContext
类型参数并调用AddDbContext
的扩展方法来完成:
public static IServiceCollection AddMyContext<T>(
this IServiceCollection services,
IConfiguration configuration) where T:DbContext
{
services.AddDbContext<T>(options =>
{
if (Helpers.IsDevelopment())
{
options.EnableSensitiveDataLogging();
options.EnableDetailedErrors();
}
options.UseNpgsql(configuration.GetConnectionString("Context"), b =>
{
b.MigrationsAssembly("App.Project.Specific");
b.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
b.EnableRetryOnFailure(5);
});
}
);
return services;
}
在应用程序的启动中,调用AddMyContext
而不是AddDbContext
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.