How to map object Id from DTO to existing object in database?

Viewed 819

I'm trying to map object Id to an existing object using automapper and EF core. My dto accepts LocationId only, but I'd like to map full Location object in WorkRecord entity if object with such id exists in database, otherwise controller will return BadRequest.

DTO:

    public class WorkRecordCreateDto
    {
        [Required]
        public int? LocationId { get; set; }
    }

Model

    public class WorkRecord
    {
        public int Id { get; set; }
        public Location Location { get; set; }
    }

Controller:

        [HttpPost]
        public ActionResult Post(WorkRecordCreateDto workRecordDto)
        {
            var workRecord = _mapper.Map<WorkRecord>(workRecordDto);
            _repository.GetRepository<WorkRecord>().Add(workRecord);
            _repository.SaveChanges();
            return Ok();

        }
1 Answers

We have an EnityConverter for this:

public class EntityConverter<TDestination> : IValueConverter<int, TDestination>
{
    private readonly ISession session;

    public EntityConverter(ISession session)
    {
        this.session = session;
    }

    public TDestination Convert(int sourceMember, ResolutionContext context)
    {
        return session.Get<TDestination>(sourceMember);
    }
}

To use this, you have to configure the mapper, that it can use DependencyInjection. We use Grace and it will be different in your environment:

container.Configure(c => c.ExportFuncWithContext<IMapper>((scope, staticContext, context)
                    => new Mapper(automapperConfig, t => scope.Locate(t))).Lifestyle.SingletonPerScope());

Now you can add the EntityConverter in the AutoMapper mapping:

CreateMap<WorkRecord, WorkRecordCreateDto>()
            .ReverseMap()
            .ForMember(d => d.Location, opts => opts.ConvertUsing<EntityConverter<WorkRecord>, int>(src => src.LocationId));
Related