首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >手动实例化多个DbContext而不注入依赖项

手动实例化多个DbContext而不注入依赖项
EN

Stack Overflow用户
提问于 2019-08-05 08:51:42
回答 1查看 3.1K关注 0票数 0

我想要创建一个ASP.Net核心web服务,它将从一个Server数据库中选择行并将它们插入到数据库中。所有数据库都具有相同的结构(相同的模型)。

我不想注入DbContext,因为我不知道我需要使用多少上下文,而且它将很难维护。

是否可以在控制器或管理器中手动创建DbContext,如:

代码语言:javascript
复制
MyContextClass dbContext = new MyContextClass("myConnectionString");

谢谢

EN

Stack Overflow用户

回答已采纳

发布于 2019-08-05 09:54:06

是的,只要创建一个新的DbContext就可以了。然而,在使用DI时,您应该编写和注入类似于DbContextFactory类的东西,您可以使用该类来创建新的上下文,并且它本身可以从您的配置中获取DbContextOptions

代码语言:javascript
复制
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;
    }
}

为了更容易使用,创建一个扩展类:

代码语言:javascript
复制
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)中从配置中添加连接字符串:

代码语言:javascript
复制
services.AddDatabase<MyDbContext>(Configuration.GetConnectionString("MyDatabase"));
票数 3
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57355118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档