0

I'm using Automapper 12 to map a model over an existing EF entity. Ignores are respected on the main entity being updated, but not on the related entities and I'm not quite sure why (lacking proper collections support?)

var model = new User() { 
  UserId = 1, 
  Name = "Joe", 
  Tickets = new List<Ticket>() { 
    TicketId = 1,
    Title = "Test Ticket", 
  }
};
var entity = await context.User.Include(x => x.Tickets).Where(x => x.UserId == userId).FirstOrDefaultAsync();

entity = _mapper.Map(model, entity);
await context.SaveChangesAsync();
// mapping profile
public class UserProfile : Profile
{
  public UserProfile()
  {
    CreateMap<DataModel.User, ApiModel.User>()
      .ForMember(x => x.Name, options => options.MapFrom(x => x.Name))
      .ForMember(x => x.Tickets, options => options.MapFrom(x => x.Tickets))
      .ForMember(x => x.UserId, options => options.Ignore());

    CreateMap<DataModel.Ticket, ApiModel.Ticket>()
      .ForMember(x => x.Title, options => options.MapFrom(x => x.Title))
      .ForMember(x => x.TicketId, options => options.Ignore());
  }
}

Looking at the above, one would expect the UserId doesn't get clobbered, and neither does the TicketId in the related entity. But what actually happens is UserId doesn't get modified, but the Ticket objects are created as new objects rather than mapping over the existing one thus giving TicketId = 0.

What's the recommended approach? Map all the related values separately?

Michael Brown
  • 1,585
  • 1
  • 22
  • 36

1 Answers1

1

Have a look at the AutoMapper Docs, where it says

When mapping to an existing collection, the destination collection is cleared first. If this is not what you want, take a look at AutoMapper.Collection.

AutoMapper can't update existing items in your collection, as it won't know which ones to update. It will therefore just clear the collection and add from source. If you use the AutoMapper.Collection extension, you can tell the Mapper how to identify which object is which, and it will update the relevant ones, delete missing ones, and create new ones.

So you would use

CreateMap<DataModel.Ticket, ApiModel.Ticket>()
    .EqualityComparison((dmt, amt) => dmt.TicketID == amt.TicketID)
    //etc

or some other property that you want to use to match the entities.

Yitz
  • 946
  • 4
  • 8