简体   繁体   中英

How do I update an entity with nested entities with AutoMapper and save the updated Entity with Entity Framework?

I've created a mapping to map a collection in the ViewModel to another collection on a Model which seems to work without a problem. After mapping, The child object of the Model has the appropriate updates.

configuration.CreateMap<SourceViewModel, Destination>()                
            .ForMember(d => d.ChildOfDestination, 
                      opt => opt.MapFrom(s => Mapper.Map<ICollection<SourceViewModel>, ICollection<Destination>>(s.ChildOfSource)));

However, on save an error is thrown:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

What I have found is ChangeTracker.Entries() has extra items with a state of "Added". For example, my Model.ChildCollection has a count of 2, but in Entries(), I have the original 2 items from ChildCollection with states of "Modified", and 2 of the same items with States of "Added"

public async Task<IHttpActionResult> Update([FromBody] SourceViewModel viewModel) {
    var model = await _repository.GetByIdAsync(viewModel.Id);
    Mapper.Map(viewModel, model);
    _repository.Update(model);
    await _unitOfWork.SaveAsync();
}

I wrote some code to get around the problem for the time being but it's a hack to a bigger problem that I'm not sure how to solve.

foreach (var child in ViewModel.Child)
{
  var record = Model.Child.SingleOrDefault(c => c.ID == child.ID);

  if (record != null)
      Mapper.Map(child, record);
  else
      Model.Child.Add(Mapper.Map<SourceViewModel, Destination>(child));
}

Entity Framework 6

Disconnected data is an old problem that precedes Entity Framework and, for that matter, most data access tools. It's never been an easy one to solve. The server sends data down the wire, not knowing what may happen to it in the client app that requested it, not even knowing if it will return. Then, suddenly, some data reappears in a request. But is it the same data? What was it up to in its absence? Did anything happen to it? Is it completely new data? So much to worry about!

Source: https://msdn.microsoft.com/da-dk/magazine/mt694083

A very good response on this site referring to the article above: https://stackoverflow.com/a/21436713/550198

Entity Framework Core / Entity Framework 7

Entity Framework Core also known as EF7 has new features that will allow you to walk the object graph. eg

context.ChangeTracker.TrackGraph(someEntity,  e => e.Entry.State = EntityState.Added);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM