本文介绍了ASP.Net vNext DbContext依赖注入多个请求问题.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ASP.Net vNext,MVC,EF7和存储库模式(这里不是问题,我不认为)...

I am attempting to use ASP.Net vNext, MVC, EF7, and the repository pattern (not the issue here, I don't think)...

我遇到的问题是,对数据库发出多个请求时,出现以下错误:已经有与此命令相关联的打开的DataReader,必须首先关闭它."

The issue I'm having is that when multiple requests are made against the database, I'm getting the following error: "There is already an open DataReader associated with this Command which must be closed first."

以下是一些代码:

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();
    }
}

控制器:

[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);
    }
}

国家资料库:

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);
    }
}

我对Location的回购设置几乎相同(当然,还有更多方法)...当我同时对我的location和状态控制器进行AJAX调用时,就会出现问题.我希望上下文的DI可以处理此类冲突,但似乎并没有这样做.是否有另一种方法可以配置它以使其正常工作,而不必回到旧的在整个存储库中创建上下文实例的方法了?我的配置是否有误?

I have pretty much the same repo setup for Locations (with a few more methods, of course)... the problem comes in when I'm making simultaneous AJAX calls to my locations and states controllers. I would expect the DI for the context to handle such collisions, but it doesn't appear to be doing so. Is there another way to configure this to work correctly without having to go back to the old way of creating an instance of my context throughout my repos? Do I have anything configured incorrectly?

推荐答案

我并不是声称自己是DI专家,但是请尝试使用AddScoped而不是AddSingleton注册您的存储库.我认为您为每个请求都获得了相同的存储库实例,这可能具有相同的DbContext实例,并且DbContext并不是线程安全的.

I don't claim to be a DI expert, but try registering your repositories with AddScoped instead of AddSingleton. I think you are getting the same instance of the repository for each request which probably has the same instance of your DbContext and DbContext is not thread safe.

此外,请确保您的连接字符串中具有MultipleActiveResultSets = true.我认为这也会导致您看到的错误.

Also, make sure you have MultipleActiveResultSets=true in your connectionstring. I think that can also cause the error you are seeing.

这篇关于ASP.Net vNext DbContext依赖注入多个请求问题.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 00:35