本文介绍了调用新的DbContext时,DbContextOptions中会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不使用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)'

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<ApplicationDbContext>类是services.AddDbContext<ApplicationDbContext>(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中会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 07:08