ASP.NET Core DbContext 注入
Posted
技术标签:
【中文标题】ASP.NET Core DbContext 注入【英文标题】:ASP.NET Core DbContext injection 【发布时间】:2017-11-12 00:12:01 【问题描述】:我有一个我正在尝试使用的ConfigurationDbContext
。它有多个参数,DbContextOptions
和 ConfigurationStoreOptions
。
如何将此 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 中的已处置对象