[英].NET Core 2.1 DbContext ObjectDisposedException Dependency Injection
[英]How do I configure a DbContext with dependency injection with .Net Core 2.1?
服务
public void ConfigureServices(IServiceCollection services)
{
string cs = Configuration.GetConnectionString("Skillcheck");
services.AddDbContext<TicketsystemContext>(options => options.UseSqlServer(cs));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
语境
public TicketsystemContext()
{
}
public TicketsystemContext(DbContextOptions<TicketsystemContext> options)
: base(options)
{
}
// ... rest of the context
例外
System.InvalidOperationException:没有为此DbContext配置数据库提供程序。 可以通过重写DbContext.OnConfiguring方法或在应用程序服务提供程序上使用AddDbContext来配置提供程序。 如果使用AddDbContext,则还应确保DbContext类型在其构造函数中接受DbContextOptions对象,并将其传递给DbContext的基本构造函数。 在Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider,IDbContextOptions contextOptions,DbContext上下文)
Microsoft.Extensions.Internal.PropertyHelper.CallNullSafePropertyGetter [TDeclaringType,TValue](Func`2 getter,Object target)的Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker()的Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()的Microsoft.AspNetCore.Mvc Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext,IModelBinder modelBinder,IValueProvider valueProvider,ParameterDescriptor参数,ModelMetadata元数据,对象值)的.ModelBinding.Binders.ComplexTypeModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext)
在Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider。<> c__DisplayClass0_0。<g__Bind | 0> d.MoveNext()
当我从上下文中删除空的构造函数时发生异常
System.InvalidOperationException:无法创建类型为'Skillcheck.Models.TicketsystemContext'的实例。 模型绑定的复杂类型不能为抽象或值类型,并且必须具有无参数构造函数。 或者,给'c'参数一个非空的默认值。 在Microsoft.AspNetCore.Mvc.ModelBindingContext.Binders.ComplexTypeModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext)在Microsoft.AspNetCore.Mvc.ModelBindingContext。 actionContext,IModelBinder modelBinder,IValueProvider valueProvider,ParameterDescriptor参数,ModelMetadata元数据,对象值)
在Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider。<> c__DisplayClass0_0。<g__Bind | 0> d.MoveNext()
我通过重写OnConfiguring暂时解决了它,但是我想了解为什么它不起作用。 我在VS2017上使用.Net Core 2.1。
解
错误是,而不是
private TicketsystemContext _c;
public HomeController(TicketsystemContext c)
{
_c = c;
}
public IActionResult Index()
{
return View(_c.User.First());
}
我用了
public IActionResult Index(TicketsystemContext c)
{
return View(c.User.First());
}
在覆盖OnConfiguring时有效,但在注入时配置时无效。
好吧,第一个错误是由于包含无参数的构造函数。 那不应该存在。 依赖注入将始终选择要满足的依赖关系最少的构造函数,这将是无参数的,但是您需要注入DbContextOptions<TContext>
。
第二个错误表明您将上下文作为参数包含在操作方法中。 我不确定为什么要这么做,但不应该这么做。 您的上下文应注入控制器本身,并在此上设置为ivar,以便您的操作可以利用ivar。 您可能可以在[FromServices]
加上参数,以指示modelbinder应该忽略它,而应该从服务集合中注入它,但是方法注入是一种反模式。
您正在将TicketsystemContext
直接注入Index
动作。
通常,应将TicketsystemContext
作为依赖项注入contructor中,如下所示:
public class HomeController : Controller
{
private readonly TicketsystemContext context;
public HomeController(TicketsystemContext context)
{
this.context = context;
}
public IActionResult Index()
{
return View(context.User.First());
}
}
如果您将TicketsystemContext
注入行动,则可以通过以下代码尝试@Chris Pratt的建议:
public IActionResult Index([FromServices]TicketsystemContext c)
{
return View(c.User.First());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.