Where to call SaveChanges () when you have multiple repositories?

6

I'm developing an application with Entity Framework, with several repositories.

Each repository encapsulates SaveChanges() of DbContext.

When a business layer operation uses multiple repositories, and data changes, I need to call SaveChanges() only once.

Obviously, I can do this in any repository, but I find it odd to have to call one at random. What is the recommendation in this situation?

EDITED

Repositories are only in interfaces for now, there is no implementation, there is one

public interface IUserRepository
{
   User getByID(string ID);
   User getByIDWithActiveGlossaries(string ID);
   IEnumerable<User> getAll();

   bool Save();
}

And there are other repositories, all implementing Save() . Save is in a base interface, I put it together here for simplicity. Save will call SaveChanges() of DbContext .

PS: I evaluated the use of UnitOfWork , but discarded, seeing no need. This is why, alias, I call SaveChanges() at the end of a full operation, which may involve several changes.

FINAL EDITION

I had discarded the use of Unit of Work because there was no need for a mechanism to group the operations, since SaveChanges() is already "all or nothing" (all operations are successful or all are reversed).

However, thanks to the answers from Hokos and Dherik, I realized that Unit of Work does not only have this functionality, but also allows you to group the Save() operation.

    
asked by anonymous 13.08.2015 / 13:08

2 answers

5

I believe the pattern Unit Of Work will solve your problem.

With it, briefly, you create a unit of work and add the repositories in it. At the end, you call the Commit() of the work unit.

Even if you do not want to share the same context between repositories, you can use the Unit of Work idea as the basis for the solution.

Here you can find a more complete example with multiple repositories.

    
13.08.2015 / 13:50
1

You can change your Save() method to receive a transaction. That way you could check if a transaction was reported, just add the object in the context and commit it in the transaction after calling all Save() . Another approach would be when you do not pass the transaction, then you could give the SaveChanges directly inside the method, it is implied that only one object is being saved.

public bool Save(TransactionScope transaction = null)
{
    if(transaction != null)
    {
     //Aqui você apenas adiciona o objeto no contexto.
    }
    else
    {
     //Aqui você salva direto o objeto.
    }
}

After passing through the% N of% you will do, just give a Commit in the transaction. If you do not have N, you called a Save() saved and that's it.

    
13.08.2015 / 14:24