Mike McCoy
Mike McCoy

Reputation: 797

Save Many to Many relationship with Entity Framework using Unit of Work Pattern

I am trying to save a many-to-many relationship with EF between Models and Options. I'm pretty sure my models are setup correctly as the framework created an OptionsModels table, and I can retrieve and populate my edit view data as intended. Saving changes back is where I'm running into the issue.

I have the following code in my controller (simplified):

        //process the selected options            
        if (editModelModel.SelectedOptionIds.Any())
        {
            modelEntity.Options = new Collection<Option>();

            foreach (var id in editModelModel.SelectedOptionIds)
            {
                modelEntity.Options.Add(_optionService.GetOption(Convert.ToInt16(id)));
            }
        }

        _modelService.Update(modelEntity);
        _unitOfWork.Save();

Update method in ModelService class:

    public void Update(Model entity)
    {
        _unitOfWork.GetRepository<Model>().Update(entity);
    }

SQL Generic Repository Method:

    public virtual void Update(TEntity entityToUpdate)
    {
        _dbSet.Attach(entityToUpdate);
        _context.Entry(entityToUpdate).State = EntityState.Modified;
    }

When I run through this code I get no errors it just doesn't update or add any data to my OptionModels table. I've been through numerous posts but can't seem to find what I'm looking for, which seems like it should be fairly common knowledge. I must just be missing something small...

Upvotes: 0

Views: 563

Answers (1)

Mister Epic
Mister Epic

Reputation: 16733

I think I see what is happening. Based on your fields in your controller and your service, it appears that you have a private _unitOfWork in both your controller and service. That could cause your issue, as you might be initiating the update via your service's unit of work BUT it is your controller's unit of work that is saving changes.

Since you appear to be instantiating two separate units of work, they won't share the same context, so one won't see what the other is doing.

Instead of instantiating a new unit of work in your service, you could pass the controller's unit of work to the service and ensure that all layers share the same context:

public class MyController{
   public MyController(){
      _uow = new UoW();
      _service = new ModelService(_uow);
   }
}

Upvotes: 1

Related Questions