resolutioncontext multiple mappings formember createmissingtypemaps beforemap c# automapper casting

c# - formember - automapper multiple mappings



AutoMapper: ¿Cómo analizar un Int desde una cadena y crear reglas basadas en el tipo de datos? (3)

Tengo dos modelos para mi formulario, un ViewModel y un ControlModel que viene de él. El ControlModel tiene todos los mismos nombres de campo y jerarquía, pero todos los campos son un tipo de datos de cadena.

¿Cómo codificaría AutoMapper para convertir un campo de cadena en entero? Intenté Int32.Parse (myString) pero Int32 no está disponible dentro de la expresión (da un error).

Mapper.CreateMap<SourceClass, DestinationClass>() .ForMember(dest => dest.myInteger, opt => opt.MapFrom(src => src.myString));

Los tipos en la clase y sus tipos de conversión correspondientes:

cadena a int, int, double, double, DateTime y bool

Además, ¿hay alguna forma de generalizar las asignaciones de manera que todos los enteros en el objetivo se analicen con esa función? En otras palabras, ¿hay una manera de crear asignaciones para tipos de datos?

EDITAR:

Esto parece prometedor:

AutoMapper.Mapper.CreateMap<string, int>() .ConvertUsing(src => Convert.ToInt32(src));

EDIT: este post es realmente útil


Puede crear propiedades en su clase de origen que conviertan campos a los tipos que existen en el destino. A continuación, utilice AutoMapper en una forma simple de vainilla.

public class source { public int _myfield; public string MyField { get { return _myfield.ToString(); } } } public class destination { public string MyField { get; set; } }


Sólo para mantenerse actualizado.
Las nuevas versiones pueden hacer algunas conversiones simples automáticamente

public class Source { public string String{ get; set; } } public class Target { public int Int { get; set; } public decimal Decimal{ get; set; } } [Fact] public void TestCustomMap() { Mapper.Initialize(cfg => cfg.CreateMap<Source, Target>() .ForMember(dest => dest.Int, opt => opt.MapFrom(src => src.String)) .ForMember(dest => dest.Decimal, opt => opt.MapFrom(src => src.String))); var target = Mapper.Instance.Map<Target>(new Source { String = "123" }); Assert.Equal(expected: 123, actual: target.Int); Assert.Equal(expected: 123m, actual: target.Decimal); //This will throw an exception //Mapper.Instance.Map<Target>(new Source { String = "123.2" }); }


Terminé haciendo algo como esto:

Mapper.CreateMap<string, int>().ConvertUsing<IntTypeConverter>(); Mapper.CreateMap<string, int?>().ConvertUsing<NullIntTypeConverter>(); Mapper.CreateMap<string, decimal?>().ConvertUsing<NullDecimalTypeConverter>(); Mapper.CreateMap<string, decimal>().ConvertUsing<DecimalTypeConverter>(); Mapper.CreateMap<string, bool?>().ConvertUsing<NullBooleanTypeConverter>(); Mapper.CreateMap<string, bool>().ConvertUsing<BooleanTypeConverter>(); Mapper.CreateMap<string, Int64?>().ConvertUsing<NullInt64TypeConverter>(); Mapper.CreateMap<string, Int64>().ConvertUsing<Int64TypeConverter>(); Mapper.CreateMap<string, DateTime?>().ConvertUsing<NullDateTimeTypeConverter>(); Mapper.CreateMap<string, DateTime>().ConvertUsing<DateTimeTypeConverter>(); Mapper.CreateMap<SourceClass, DestClass>(); Mapper.Map(mySourceObject, myDestinationObject);

Y las clases a las que hace referencia (primer borrador):

// TODO: Boil down to two with Generics if possible #region AutoMapTypeConverters // Automap type converter definitions for // int, int?, decimal, decimal?, bool, bool?, Int64, Int64?, DateTime // Automapper string to int? private class NullIntTypeConverter : TypeConverter<string, int?> { protected override int? ConvertCore(string source) { if (source == null) return null; else { int result; return Int32.TryParse(source, out result) ? (int?) result : null; } } } // Automapper string to int private class IntTypeConverter : TypeConverter<string, int> { protected override int ConvertCore(string source) { if (source == null) throw new MappingException("null string value cannot convert to non-nullable return type."); else return Int32.Parse(source); } } // Automapper string to decimal? private class NullDecimalTypeConverter : TypeConverter<string, decimal?> { protected override decimal? ConvertCore(string source) { if (source == null) return null; else { decimal result; return Decimal.TryParse(source, out result) ? (decimal?) result : null; } } } // Automapper string to decimal private class DecimalTypeConverter : TypeConverter<string, decimal> { protected override decimal ConvertCore(string source) { if (source == null) throw new MappingException("null string value cannot convert to non-nullable return type."); else return Decimal.Parse(source); } } // Automapper string to bool? private class NullBooleanTypeConverter : TypeConverter<string, bool?> { protected override bool? ConvertCore(string source) { if (source == null) return null; else { bool result; return Boolean.TryParse(source, out result) ? (bool?) result : null; } } } // Automapper string to bool private class BooleanTypeConverter : TypeConverter<string, bool> { protected override bool ConvertCore(string source) { if (source == null) throw new MappingException("null string value cannot convert to non-nullable return type."); else return Boolean.Parse(source); } } // Automapper string to Int64? private class NullInt64TypeConverter : TypeConverter<string, Int64?> { protected override Int64? ConvertCore(string source) { if (source == null) return null; else { Int64 result; return Int64.TryParse(source, out result) ? (Int64?)result : null; } } } // Automapper string to Int64 private class Int64TypeConverter : TypeConverter<string, Int64> { protected override Int64 ConvertCore(string source) { if (source == null) throw new MappingException("null string value cannot convert to non-nullable return type."); else return Int64.Parse(source); } } // Automapper string to DateTime? // In our case, the datetime will be a JSON2.org datetime // Example: "/Date(1288296203190)/" private class NullDateTimeTypeConverter : TypeConverter<string, DateTime?> { protected override DateTime? ConvertCore(string source) { if (source == null) return null; else { DateTime result; return DateTime.TryParse(source, out result) ? (DateTime?) result : null; } } } // Automapper string to DateTime private class DateTimeTypeConverter : TypeConverter<string, DateTime> { protected override DateTime ConvertCore(string source) { if (source == null) throw new MappingException("null string value cannot convert to non-nullable return type."); else return DateTime.Parse(source); } } #endregion