2

In my WebAPI controller I have this:

   [HttpDelete]
    public HttpResponseMessage DeleteFolder(int id)
    {
        _service.DeleteFolder(id);
        return Request.CreateResponse(HttpStatusCode.OK, "Deleted");
    }

_service is a db access service using _db - an instance of my project's DbContext, defined once in the constructor of the service class.

In my client, I used a for loop to send a bunch of asynchronous AJAX calls to the delete method, attempting to delete multiple folders in succession. That's when stuff like this:

The underlying provider failed on Open.

and this:

The context cannot be used while the model is being created.

started happening. I have a feeling that it's due to race conditions but I'm not sure how to go about fixing it, if that's the case. Should I be creating a new instance of dbcontext for every call? If so, where should this be created? Within each method of repository.cs (where a single dbContext is created for every method's use)?

Any help would be much appreciated.

SB2055
  • 12,272
  • 32
  • 97
  • 202

1 Answers1

0

Yes, you need a separate DbContext per call. From the docs;

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

What you could do (for example, depending on how you're using transactions) is to use the Unit of Work pattern, which if EF's case basically means wrapping your DbContext in a class (you don't want it exposing EF specific classes like DbContext to your business classes) so that you in your application code (or, depending on layering, business code) can write something like;

[HttpDelete]
public HttpResponseMessage DeleteFolder(int id)
{
    using(var uow = new UnitOfWork()) {  // Creates a new DbContext
        _service.DeleteFolder(uow, id);
        uow.Commit();          
        return Request.CreateResponse(HttpStatusCode.OK, "Deleted");
    }                                    // Uncommitted UoW rolls back on Dispose
}                                        // ie on unhandled exceptions.

...or if you think passing the UoW with every service/repository method is annoying (I do), you can let the UnitOfWOrk constructor save it as the "currently active Unit of Work" in HttpContext.Current.Items, so that any service/repository can fetch the current Unit of Work when needed.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • Thank you for your time... though I'm a bit lost. Can you give an example of the latter solution? I have over 100 methods so if there's an alternative to updating every one, I'd like to pursue it. – SB2055 Jul 07 '13 at 06:38
  • And why is it that none of the Pluralsight videos on EF seem to mention this? – SB2055 Jul 07 '13 at 14:11