问题描述
我没有使用 DI,只是想从我的控制器中调用 DbContext.我正在努力弄清楚选项"应该是什么?
I am not using DI and simply want to invoke a DbContext from within my controller. I am struggling to figure out what the 'options' should be?
ApplicationDbContext.cs
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Gig> Gigs { get; set; }
public DbSet<Genre> Genres { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
GigsController.cs
GigsController.cs
public class GigsController : Controller
{
private ApplicationDbContext _context;
public GigsController()
{
_context = new ApplicationDbContext();
}
public IActionResult Create()
{
var viewModel = new GigFormViewModel
{
Genres = _context.Genres.ToList()
};
return View(viewModel);
}
}
问题出在我的 GigsController 构造函数中:
The issue is stemming in my GigsController constructor:
_context = new ApplicationDbContext();
我出错了,因为我需要将某些内容传递到 ApplicationDbContext.没有给出对应于 'ApplicationDbContext.ApplicationDbContext(DbContextOptions)' 的必需形式参数 'options' 的参数
I am erroring out because I need to pass something into the ApplicationDbContext. There is no argument given that corresponds to the required formal parameter 'options' of 'ApplicationDbContext.ApplicationDbContext(DbContextOptions)'
我尝试在从 base() 派生的 ApplicationDbContext 中创建一个默认构造函数,但这也不起作用.
I tried creating a default constructor in ApplicationDbContext derived from base(), but that didn't work either.
在我的 startup.cs 中,我已经配置了 ApplicationDbContext
In my startup.cs, I have configured the ApplicationDbContext
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
推荐答案
如果您确实想要手动创建上下文,那么您可以配置如下:
If you really want to create the context manually, then you can configure it like this:
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(Configuration.GetConnectionStringSecureValue("DefaultConnection"));
_context = new ApplicationDbContext(optionsBuilder.Options);
(DbContextOptionsBuilder
类是 services.AddDbContext(options =>
) 中 options
参数的类型.但是在控制器中,您无权访问 Configuration
对象,因此您必须将其公开为 Startup.cs
中的静态字段或使用其他一些技巧,这都是不好的做法.
(The DbContextOptionsBuilder<ApplicationDbContext>
class is the type of options
argument in services.AddDbContext<ApplicationDbContext>(options =>
). But in the controller, you don't have access to Configuration
object, so you would have to expose it as a static field in Startup.cs
or use some other trick, which is all bad practice.
获取ApplicationDbContext
的最佳方式是通过DI获取:
The best way to obtain ApplicationDbContext
is to get it through DI:
public GigsController(ApplicationDbContext context)
{
_context = context;
}
DI 容器将负责实例化和处理ApplicationDbContext
.请注意,您已在 Startup.cs
中正确配置了所有内容:
The DI container will take care of instantiating and disposing of ApplicationDbContext
. Note that you have everything correctly configured in Startup.cs
:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
那是在配置 DI,为什么不直接使用它呢?
That's configuring DI, so why not just use it?
关于 DbContext
的默认构造函数的更多说明:在 EF6 中它是这样完成的:public ApplicationDbContext(): base("DefaultConnection") {}
.然后基础对象将使用System.Configuration.ConfigurationManager
静态类从web.config
获取名为DefaultConnection
的连接字符串.新的 Asp.net Core 和 EF Core 旨在尽可能解耦,因此不应依赖于任何配置系统.相反,您只需传递一个 DbContextOptions
对象 - 创建该对象并配置它是一个单独的问题.
One more note about the default constructor of DbContext
: In EF6 it was done like this: public ApplicationDbContext(): base("DefaultConnection") {}
. Then the base object would use System.Configuration.ConfigurationManager
static class to obtain the connection string named DefaultConnection
from web.config
. The new Asp.net Core and EF Core is designed to be as much decoupled as possible, so it should not take dependencies on any configuration system. Instead, you just pass a DbContextOptions
object - creating that object and configuring it is a separate concern.
这篇关于调用新的 DbContext 时,DbContextOptions 中的内容是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!