Dependency injection ASP.Net vNext DbContext依赖项注入存在多个请求问题。
我正在尝试使用ASP.NETVNEXT、MVC、EF7和存储库模式(我认为这不是问题所在) 我遇到的问题是,当对数据库发出多个请求时,我会得到以下错误:“已经有一个与此命令关联的打开的DataReader,必须先关闭它。” 下面是一些代码:Dependency injection ASP.Net vNext DbContext依赖项注入存在多个请求问题。,dependency-injection,repository-pattern,asp.net-core,asp.net-core-mvc,Dependency Injection,Repository Pattern,Asp.net Core,Asp.net Core Mvc,我正在尝试使用ASP.NETVNEXT、MVC、EF7和存储库模式(我认为这不是问题所在) 我遇到的问题是,当对数据库发出多个请求时,我会得到以下错误:“已经有一个与此命令关联的打开的DataReader,必须先关闭它。” 下面是一些代码: public class Startup { public IConfiguration Configuration { get; set; } public Startup(IHostingEnvironment env) {
public class Startup
{
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment env)
{
Configuration = new Configuration().AddJsonFile("config.json").AddEnvironmentVariables();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Register Entity Framework
services.AddEntityFramework(Configuration)
.AddSqlServer()
.AddDbContext<MyDbContext>();
services.AddSingleton<ILocationRepo, LocationRepo>();
services.AddSingleton<IStateRepo, StateRepo>();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
var testData = ActivatorUtilities.CreateInstance<TestData>(app.ApplicationServices);
testData.InitializeData();
}
}
公共类启动
{
公共IConfiguration配置{get;set;}
公共启动(IHostingEnvironment环境)
{
Configuration=new Configuration().AddJsonFile(“config.json”).AddEnvironmentVariables();
}
public void配置服务(IServiceCollection服务)
{
services.AddMvc();
//注册实体框架
服务.附加框架(配置)
.AddSqlServer()文件
.AddDbContext();
services.AddSingleton();
services.AddSingleton();
}
公共void配置(IApplicationBuilder应用程序)
{
app.UseMvc();
var testData=ActivatorUtilities.CreateInstance(app.ApplicationServices);
testData.InitializeData();
}
}
控制员:
[Route("api/[controller]")]
public class LocationsController : Controller
{
private readonly ILocationRepo _repo;
public LocationsController(ILocationRepo repo)
{
_repo = repo;
}
// GET: api/locations
[HttpGet]
public List<Location> Get()
{
return _repo.All.ToList();
}
// GET api/locations/5
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var ret = _repo.GetById(id);
if (ret == null)
return new HttpNotFoundResult();
return new ObjectResult(ret);
}
// POST api/locations
[HttpPost]
public IActionResult Post([FromBody]Locationvalue)
{
var ret = _repo.AddOrUpdate(value);
if (ret == null)
return new BadRequestResult();
return new ObjectResult(ret);
}
// PUT api/locations/5
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody]Location value)
{
var ret = _repo.AddOrUpdate(value);
if (id == 0 || ret == null)
return new BadRequestResult();
return new ObjectResult(ret);
}
// DELETE api/locations/5
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var existing = _repo.GetById(id);
if (existing == null)
return new HttpNotFoundResult();
bool ret = _repo.TryDelete(id);
return new ObjectResult(ret);
}
}
[路由(“api/[控制器]”)]
公共类位置控制器:控制器
{
私人只读ILocationRepo\u repo;
公共场所控制人(ILocationRepo-repo)
{
_回购=回购;
}
//获取:api/位置
[HttpGet]
公共列表Get()
{
return _repo.All.ToList();
}
//获取api/locations/5
[HttpGet(“{id}”)]
公共IActionResult Get(int id)
{
var ret=_repo.GetById(id);
if(ret==null)
返回新的HttpNotFoundResult();
返回新的ObjectResult(ret);
}
//张贴空气污染指数/地点
[HttpPost]
公共IActionResult帖子([FromBody]Locationvalue)
{
var ret=_repo.AddOrUpdate(值);
if(ret==null)
返回新的BadRequestResult();
返回新的ObjectResult(ret);
}
//放置api/位置/5
[HttpPut(“{id}”)]
公共IActionResult Put(int id,[FromBody]位置值)
{
var ret=_repo.AddOrUpdate(值);
if(id==0 | | ret==null)
返回新的BadRequestResult();
返回新的ObjectResult(ret);
}
//删除api/locations/5
[HttpDelete(“{id}”)]
公共IActionResult Delete(int id)
{
var existing=_repo.GetById(id);
if(现有==null)
返回新的HttpNotFoundResult();
bool ret=_repo.TryDelete(id);
返回新的ObjectResult(ret);
}
}
国家知识库:
public class StateRepo : IStateRepo
{
private readonly MyDbContext context;
public StateRepo(MyDbContext diContext)
{
context = diContext;
}
public IEnumerable<State> All
{
get
{
return context.States;
}
}
public State GetById(int id)
{
return context.States.FirstOrDefault(x => x.Id == id);
}
}
公共类StateRepo:IStateRepo
{
私有只读MyDbContext上下文;
public StateRepo(MyDbContext双上下文)
{
上下文=双上下文;
}
公共数字所有
{
得到
{
返回上下文。状态;
}
}
公共状态GetById(int id)
{
返回context.States.FirstOrDefault(x=>x.Id==Id);
}
}
我有几乎相同的位置回购设置(当然还有一些方法)。。。当我同时对我的位置和状态控制器进行AJAX调用时,问题就出现了。我希望上下文的DI能够处理此类冲突,但它似乎没有这样做。是否有另一种方法可以将其配置为正常工作,而不必返回到在整个repo过程中创建上下文实例的旧方法?我是否有任何配置不正确的地方?我并不自称是DI专家,但请尝试使用AddScoped而不是AddSingleton注册您的存储库。我认为,对于每个请求,您都会得到相同的存储库实例,其中可能有相同的DbContext实例,并且DbContext不是线程安全的
另外,确保connectionstring中有MultipleActiveResultSets=true。我认为这也可能导致您看到的错误。我并不声称自己是DI专家,但请尝试使用AddScoped而不是AddSingleton注册您的存储库。我认为,对于每个请求,您都会得到相同的存储库实例,其中可能有相同的DbContext实例,并且DbContext不是线程安全的 另外,确保connectionstring中有MultipleActiveResultSets=true。我认为这也会导致你看到的错误