首页 > 解决方案 > 如何将对象 ID 从 DTO 映射到数据库中的现有对象?

问题描述

我正在尝试使用 automapper 和 EF 核心将对象 ID 映射到现有对象。我的 dto 只接受LocationId,但如果数据库中存在具有此类 id 的对象,我想LocationWorkRecord实体中映射完整对象,否则控制器将返回BadRequest.

DTO:

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

模型

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

控制器:

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

        }

标签: c#asp.net-core.net-coreentity-framework-coreautomapper

解决方案


为此,我们有一个 EnityConverter:

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);
    }
}

要使用它,您必须配置映射器,它可以使用 DependencyInjection。我们使用 Grace,它会在您的环境中有所不同:

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

现在您可以在 AutoMapper 映射中添加 EntityConverter:

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

推荐阅读