Dependency injection ASP.Net vNext DbContext依赖项注入存在多个请求问题。

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) {

我正在尝试使用ASP.NETVNEXT、MVC、EF7和存储库模式(我认为这不是问题所在)

我遇到的问题是,当对数据库发出多个请求时,我会得到以下错误:“已经有一个与此命令关联的打开的DataReader,必须先关闭它。”

下面是一些代码:

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。我认为这也会导致你看到的错误