如何在EF Core中实例化DbContext

joh*_*dle 18 c# entity-framework-core .net-core asp.net-core

我也设置了.net核心项目和数据库上下文.但我不能开始使用dbContext但由于此错误 -

"没有给出符合所需形式参数'选项'的论据"

控制器:

public IActionResult Index()
{
    using (var db = new BlexzWebDb())
    {

    }
    return View();
}
Run Code Online (Sandbox Code Playgroud)

Dbcontext代码:

public class BlexzWebDb : DbContext
{
    public BlexzWebDb(DbContextOptions<BlexzWebDb> options)
       : base(options)
    { }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<AssignedRole> AssignedRoles { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

错误图片附.是什么可能解决这个问题?提前致谢

PIC

Ste*_*fan 32

在EF Core中,将一些DbContextOptions传递给构造函数是很常见的.

所以一般来说,构造函数看起来像这样:

public BlexzWebDb(DbContextOptions<BlexzWebDb> options) : base(options)
Run Code Online (Sandbox Code Playgroud)

正如你在那里看到的那样,没有参数构造函数形式的有效重载:

因此,这不起作用:

using (var db = new BlexzWebDb())
Run Code Online (Sandbox Code Playgroud)

代替


.Net Core已经在其中实现了IoC.好的,这意味着; 你没有创建一个上下文,你要求框架根据你之前定义的一些规则给你一个.

示例:在某处您将注册dbcontext,(Startup.cs):

//typical configuration part of .net core
public void ConfigureServices(IServiceCollection services)
{
    //some mvc 
    services.AddMvc();

    //hey, options! 
    services.AddDbContextPool<BlexzWebDb>(options => 
           options.UseSqlServer(Configuration.GetConnectionString("BlexzWebConnection")));
    //...etc
Run Code Online (Sandbox Code Playgroud)

现在注册部分已完成,您可以从框架中检索您的上下文.例如:通过控制器中的构造函数反转控制:

public class SomeController : Controller
{
    private readonly BlexzWebDb _db;

    //the framework handles this
    public SomeController(BlexzWebDb db)
    {
        _db = db;
    }

    //etc.
Run Code Online (Sandbox Code Playgroud)

  • 你厉害吗!多谢,伙计。非常漂亮和干净描述 (2认同)
  • 请注意,如果你使用`.AddDbContext <>`,你的整个ioc树现在暴露给ef(例如,对于像日志这样的东西,从Ef 2.1开始,你甚至可以将服务注入到模型中).这对你来说可能或不重要,但我们明确选择退出这种模式,例如:) (2认同)

Qam*_*man 27

从ConnectionString实例化DbContext的新对象

var connectionstring = "Connection string";

var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
    optionsBuilder.UseSqlServer(connectionstring);


ApplicationDbContext dbContext = new ApplicationDbContext(optionsBuilder.Options);

// Or you can also instantiate inside using

using(ApplicationDbContext dbContext = new ApplicationDbContext(optionsBuilder.Options))
{
   //...do stuff
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是正确的答案。如果您不想要 DI,您不应该受到同侪的压力而这样做。 (15认同)
  • @DerekPollard OP 询问如何实例化 EF 上下文,这个答案展示了如何实例化。由于OP具体不明白他们必须向该构造函数提供参数,因此回答者也展示了如何传递选项。 (11认同)
  • 我同意@neeohw!这一定是正确的答案。例如,我需要一个单独的连接字符串用于迁移(在后台任务中),具有不同的权限,并且我不需要在这里实现依赖项(而且很难做到) (6认同)
  • 这如何回答这个问题? (3认同)
  • 我们可以像这样实例化DbContext (3认同)

has*_*san 17

除了@Stefan的回答之外,还有另一种方法可以实现这一目标.您可以在DbContext类的OnCongfiguring方法中设置db连接字符串,而无需在startup.cs中添加DbContext服务.

Setting.cs

public static class Setting
{
    public static string ConnectionString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs

Setting.ConnectionString = Configuration.GetSection("ConnectionStrings:BlexzDbConnection").Value;
Run Code Online (Sandbox Code Playgroud)

BlexzWebDb.cs

public class BlexzWebDb : DbContext 
{
   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       if (!optionsBuilder.IsConfigured)
       {
           optionsBuilder.UseSqlServer(Setting.ConnectionString);
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

HomeController.cs

public class HomeController : Controller
{
    private readonly BlexzWebDb db;

    public HomeController()
    {
        this.db = new BlexzWebDb();
    }

    //etc.
Run Code Online (Sandbox Code Playgroud)

  • 那么“Setting”类呢?如何实例化配置、获取连接并保存到此类? (2认同)

Sam*_*Sch 5

EF Core 3.1 的代码示例:

public class Test
{
    private readonly IServiceProvider _serviceProvider;

    public Test(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public async Task<RequestResult> Handle(...)
    {
        await using var context = CreateContext();
        ...
    }

    private DocumentContext CreateContext()
    {
        var options = _serviceProvider.GetService<IOptions<DocumentContextOptions>>();
        return new DocumentContext(options);
    }
}
Run Code Online (Sandbox Code Playgroud)