ASP.NET Core DbContext 注入

Posted

技术标签:

【中文标题】ASP.NET Core DbContext 注入【英文标题】:ASP.NET Core DbContext injection 【发布时间】:2017-11-12 00:12:01 【问题描述】:

我有一个我正在尝试使用的ConfigurationDbContext。它有多个参数,DbContextOptionsConfigurationStoreOptions

如何将此 DbContext 添加到我在 ASP.NET Core 中的服务中?

我在 Startup.cs 中尝试了以下操作:

ConfigureServices
....
services.AddDbContext<ConfigurationDbContext>(BuildDbContext(connString));
....


private ConfigurationDbContext BuildDbContext(string connString)

    var builder = new DbContextOptionsBuilder<ConfigurationDbContext>();
    builder.UseSqlServer(connString);

    var options = builder.Options;

    return new ConfigurationDbContext(options, new ConfigurationStoreOptions());

【问题讨论】:

你用的是mssql server吗 是的。但是,要构造 dbcontext,我需要向它传递另一个参数。 我还添加了示例链接 【参考方案1】:

AddDbContext implementation 只是在 DI 中注册上下文本身及其公共依赖项。 手动注册 DbContext 是完全合法的,而不是 AddDbContext 调用:

services.AddTransient<FooContext>();

此外,您可以使用工厂方法来传递参数(这是回答问题):

services.AddTransient<FooContext>(provider =>

    //resolve another classes from DI
    var anyOtherClass = provider.GetService<AnyOtherClass>();

    //pass any parameters
    return new FooContext(foo, bar);
);

P.S.,一般来说,您不必注册 DbContextOptionsFactory 和默认 DbContextOptions 来解析 DbContext 本身,但在特定情况下可能是必要的。

【讨论】:

链接断开 - 这是文件github.com/aspnet/EntityFrameworkCore/blob/master/src/EFCore/… 看起来 AddDbContextPool 也一样 @Simon_Weaver 谢谢,我已经更新了链接。 DbContextPool 我猜是在 Core 2.0 中添加的。【参考方案2】:

您可以在 startup.cs 中使用它。

详细信息:https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

详细示例:Getting started with ASP.NET Core MVC and Entity Framework Core

public void ConfigureServices(IServiceCollection services)

    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>options.
       UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

【讨论】:

【参考方案3】:

要将DbContext 注册为IServiceCollection 中的服务,您有两种选择:(我们假设您要连接到SQL Server 数据库)

使用 AddDbContext

services.AddDbContext<YourDbContext>(o=>o.UseSqlServer(Your Connection String));

使用 AddDbContextPool

services.AddDbContextPool<YourDbContext>(o=>o.UseSqlServer(Your Connection String));

您可能会看到这两者在写作方面有相似之处,但实际上它们在概念方面存在一些根本差异。 @GabrielLuci 对这两者之间的差异做出了很好的回应:https://***.com/a/48444206/1666800

另请注意,您可以将连接字符串存储在 appsettings.json 文件中,然后使用:Configuration.GetConnectionString("DefaultConnection")ConfigureServices 文件中的 ConfigureServices 方法中读取它。

【讨论】:

我有一个问题。如果我在 StartUp.cs 中添加 dbcontext,我是否必须使用 AddSingleton 或 'AddScoped` 或 AddTransient 等? @Hello 从 .NET core 2.0 开始,使用 AddDbContextPool 您不需要使用 AddTransient 或 AddSingleton 或 AddScoped 方法。阅读这些以获取更多信息:***.com/a/44484724/1666800,***.com/questions/48443567/… 感谢您的热情回复,我不使用 AddDbContextPool。我只是使用 AddDbContext。因为我跟了here的例子,没有用到这种东西,我看不懂。 @你好很好。你可以在这里阅读更多关于这两个函数的信息:docs.microsoft.com/en-us/dotnet/api/…,docs.microsoft.com/en-us/dotnet/api/… 谢谢,我明白了。默认为AddScoped【参考方案4】:

试试这个注入你的 ef 上下文 - 从 IDbContext 继承上下文

1-将您的上下文添加到服务中:

        public void ConfigureServices(IServiceCollection services)
    
        services.AddDbContext<NopaDbContext>(
                        options => options
                        .UseLazyLoadingProxies()
                        .UseSqlServer(Configuration.GetConnectionString("NopaDbContext")),ServiceLifetime.Scoped);

2-注入你的上下文:

    private readonly IDbContext _context;

    public EfRepository(NopaDbContext context)
    
        this._context = context;
    

    protected virtual DbSet<TEntity> Entities
    
        get
        
            if (_entities == null)
                _entities = _context.Set<TEntity>();

            return _entities;
        
    

【讨论】:

【参考方案5】:

您可以将 db context 的所有参数放在一个类 AppDbContextParams 中并注册一个工厂来为 appdbcontext 创建该对象:

services.AddScoped(sp =>
            
                var currentUser = sp.GetService<IHttpContextAccessor>()?.HttpContext?.User?.Identity?.Name;
                return new AppDbContextParams  GetCurrentUsernameCallback = () => currentUser ?? "n/a" ;
            );

【讨论】:

【参考方案6】:

EF Core 6 / .NET 6 进行了一些更改,使其更容易(并且受支持)同时注册 DbContext 和 DbContextPool 以用于不同的用途。

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-6.0/whatsnew#dbcontext-factory-improvements

【讨论】:

以上是关于ASP.NET Core DbContext 注入的主要内容,如果未能解决你的问题,请参考以下文章

注入 DbContext 时无法访问 ASP.NET Core 中已释放的对象

是否可以在 Asp.net Core 解决方案的单独层中管理 DBContext 的注入

C#:使用 IQueryable 注入 DbContext 时,无法访问 ASP.NET Core 中的已处置对象

ASP.NET Core 2 中的依赖注入引发异常

ASP.NET Core Web API - 如何在中间件管道中隐藏 DbContext 事务?

如何使用 ASP.NET Core 从 DbContext 中的 JWT 获取用户名?