0

I'm working on an application which uses Breeze and Entity Framework 6, with the Unit of Work and Repository patterns. Currently, we're exploring the possibility of using a static UnitOfWork instance within the application. I've set this up in our controller by doing:

public class BreezeController : ApiController
{
    private static readonly UnitOfWork _unit = new UnitOfWork();
    ...
    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        return _unit.SaveChanges(saveBundle);
    }
}

Here, the UnitOfWork class contains the EFContextProvider:

public class UnitOfWork
{
    private readonly EFContextProvider<MyContext> _contextProvider = new EFContextProvider<MyContext>();
    ...
    public SaveResult SaveChanges(JObject saveBundle)
    {
        return _contextProvider.SaveChanges(saveBundle);
    }
}

This seems to work fine when querying the database and when saving new entities into the database. However, after the first call to saveChanges() in the front-end, any subsequent query to the database fails with the error: "Value cannot be null. Parameter name: connection". I've done a little digging and it seems that the connection to the database is reset once SaveChanges has completed (for example, EntityConnection.ConnectionString in the ContextProvider gets set to an empty string). I presume that this is what causes the error (and, of course, this isn't a problem when not using a static UnitOfWork since a new instance of the EFContextProvider will be created for the next query in that case).

Assuming this is the problem, is there a way to prevent the EFContextProvider from resetting the database connection when calling SaveChanges? Or is there a way that I can force it to re-establish the connection in time for the next query? On the other hand, is there some reason why I shouldn't be trying to use a static instance of the EFContextProvider?

2 Answers2

2

EFContextProvider is not thread-safe. EFContextProvider creates and uses a DbContext, and DbContext is not thread safe. The best way to use non-thread-safe objects is to make sure to create a new instance for each thread, or each HTTP request in web apps. That is what is recommended for EFContextProvider: create a new one each time you need one.

The UnitOfWork encapsulates a single change set. You should create a new UnitOfWork instance for each set of changes that your app will make.

Community
  • 1
  • 1
Steve Schmitt
  • 3,124
  • 12
  • 14
0

We were getting the same error and it turns out it was caused by a trigger on the table we were updating. Since we didn't need the trigger anymore, we deleted it and that solved the problem without getting into depth why the trigger was causing it. It was a trigger on UPDATE and it was INSERTING records into another table. I know this is not a solution that you could apply across the board, but thought I would share in case it helps someone.