Pregunta

Me gustaría utilizar para mapear AutoMapper mis objetos del modelo de objetos de la base. Deje objeto de base es por ejemplo más de 30 campos y quiero mapear 10 de las 20 propiedades de mi modelo. Para que sea necesario que más complejo para asignar diferentes propiedades cuando actualizar el registro que cuando inserto nuevo registro a la base de datos.

La solución que estoy usando es la creación de 2 clases genéricas de inserción y actualización del perfil y la asignación que especifica tanto asignaciones.

El siguiente ejemplo:

public abstract class SyncMappingWrapper<TFrom> where TFrom : class
{
    protected SyncMappingWrapper(TFrom model)
    {
        Model = model;
    }

    public TFrom Model { get; private set; }
}

public class Update<TFrom> : SyncMappingWrapper<TFrom> where TFrom : class
{
    public Update(TFrom model)
        : base(model)
    {
    }
}

public class Insert<TFrom> : SyncMappingWrapper<TFrom> where TFrom : class
{
    public Insert(TFrom model)
        : base(model)
    {
    }
}

El mapeo, sin embargo, es cada vez más desagradable como la complejidad ciclomática va en el cielo (más de 50), ya que necesito para definir Ignorar () para todas las propiedades que no se asignan:

CreateMap<Update<OracleModel>, LiveModel>()
            .ForMember(des => des.ApprovedBy, opt => opt.Ignore())
            .ForMember(des => des.ApprovedDate, opt => opt.Ignore())
            ...
            .ForMember(des => des.UNSPSC, opt => opt.Ignore())
            .ForMember(des => des.BaseUnit, opt => opt.MapFrom(src => src.Model.UOM.BaseUOM.PerSalesUnit))
            .ForMember(des => des.BaseUOM, opt => opt.MapFrom(src => src.Model.UOM.BaseUOM.UnitOfMeasure.Code))
            .ForMember(des => des.SalesUnit, opt => opt.MapFrom(src => src.Model.UOM.SalesUOM.PerSalesUnit))
            .ForMember(des => des.SalesUOM, opt => opt.MapFrom(src => src.Model.UOM.SalesUOM.UnitOfMeasure.Code))
            .ForMember(des => des.OrderUnit, opt => opt.MapFrom(src => src.Model.UOM.OrderUOM.PerSalesUnit))
            .ForMember(des => des.OrderUOM, opt => opt.MapFrom(src => src.Model.UOM.OrderUOM.UnitOfMeasure.Code))
            .ForMember(des => des.SalesPrice, opt => opt.MapFrom(src => src.Model.Price.Value))
            .ForMember(des => des.Alternate, opt => opt.Ignore())
            .ForMember(des => des.ManufacturerID, opt => opt.Ignore())
            .ForMember(des => des.ProductCode, opt => opt.MapFrom(src => src.Model.ProductCode))
            .ForMember(des => des.ProductName, opt => opt.MapFrom(src => src.Model.ProductName))
            .ForMember(des => des.ProductHTML, opt => opt.Ignore())
            .ForMember(des => des.Version, opt => opt.Ignore())
            ...
            .ForMember(des => des.UnitsOfMeasure2, opt => opt.Ignore())
            .ForMember(des => des.Manufacturer, opt => opt.Ignore());

He resuelto el problema de la inserción de registro nuevo mediante la creación de nuevo objeto:

CreateMap<Insert<OracleModel>, LiveModel>()
            .ConstructUsing(x => new LiveModel
                {
                    BaseUnit = x.Model.UOM.BaseUOM.PerSalesUnit,
                    BaseUOM = x.Model.UOM.BaseUOM.UnitOfMeasure.Code,
                    SalesUnit = x.Model.UOM.SalesUOM.PerSalesUnit,
                    SalesUOM = x.Model.UOM.SalesUOM.UnitOfMeasure.Code,
                    OrderUnit = x.Model.UOM.OrderUOM.PerSalesUnit,
                    OrderUOM = x.Model.UOM.OrderUOM.UnitOfMeasure.Code,
                    SalesPrice = x.Model.Price.Value,
                    LeadTime = x.Model.LeadTime,
                    ProductCode = x.Model.ProductCode,
                    ProductName = x.Model.ProductName,
                    SupplierCode = x.Model.SupplierCode,
                    Weight = x.Model.Weight
                })
            .ForAllMembers(xc => xc.Ignore());

Pero no funciona si hay actualizaciones en el que necesito mapear las propiedades de un objeto existente y no nueva instancia:

        Mapper.Map(update, existingRecord);

Yo preferiría evitar DynamicMap () para mantener el control total sobre el mapeo (por lo que no voy a mapear una propiedad aleatoria por error). Mi objetivo es resolver un problema complejidad ciclomática. Por favor, no sugieren ValueInjecter o cualquier otro método. Busco solución dentro AutoMapper.

¿Fue útil?

Solución

Es cinco años más tarde, pero aquí es una sugerencia para reducir la complejidad de este problema de asignación. Puede crear una extensión que le ayudará a ignorar todos los miembros en un primer momento:

public static class AutoMapperExtension {
    public static IMappingExpression<TSource, TDest> IgnoreAllMembers<TSource, TDest>(this IMappingExpression<TSource, TDest> expression) {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}

A continuación, se utiliza para definir sólo las asignaciones que desea realizar:

Mapper.CreateMap<Insert<OracleModel>, LiveModel>()
      .IgnoreAllMembers()
      .ForMember(d => d.BaseUnit, o => o.MapFrom(s => s.Model.UOM.BaseUOM.PerSalesUnit))
      /* Mapping for other members here. */;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top