Tengo un público que enfrenta la interfaz que estoy tratando de mapa de dos diferentes enumeraciones para cada uno de los otros. Traté de usar el siguiente código:

Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>();

Cuando eso no funciona, he intentado:

Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>().ConvertUsing(x => (Common.ValidationResultType)((int)x));

Pero que no parece funcionar bien. Existe de todos modos para obtener automapper para manejar esta situación?

  • ¿Te aparece un error? Lo que no funcionó?
  • He recibido una «Falta el tipo de configuración del mapa o no se admite la asignación.» error.
  • Puede publicar su enumeraciones?
InformationsquelleAutor Jeffrey Lott | 2012-06-29

8 Comentarios

  1. 41

    Usted no necesita hacer CreateMap de tipo enum. Acaba de deshacerse de la CreateMap llamada y se debe trabajar, siempre y cuando los nombres y/o valores coinciden entre tipos enum.

    • Cuando se sigue esta práctica, se adapta utilizando el valor de enumeración o nombre de miembro ?
    • ¿Y si los nombres y los valores no coinciden?
    • A continuación, deberá crear un tipo de convertidor.
    • empList.Proyecto().A<destino.Empleado>(). Si la fuente de los Empleados y el destino de los Empleados contener la Enumeración. Entonces no va a funcionar. Se da la excepción de los Incapaces mapa Enum a Int 32
    • «Usted no necesita hacer X con Y» no es una respuesta a «¿Cómo puedo hacer X con Y». Por supuesto, nunca está de más preguntar si es realmente necesario, muchas veces no lo es.
    • la pregunta era «¿cómo puedo asignar dos enumeraciones utilizando AutoMapper». Mi respuesta es la respuesta. El resto de la pregunta comenzó a caminar por el camino equivocado acerca de las cosas de la OP intentado. Mi respuesta les puso en el camino correcto.
    • Creo que he hecho una mala suposición de que «Usted no necesita hacer CreateMap para los tipos enum» significaba no uso AutoMapper; mis disculpas. Para aquellos que buscan una respuesta que se acomode a los tipos enum con diferentes nombres y valores, por favor siga leyendo.
    • Me estoy perdiendo algo? Estoy recibiendo un error «no se puede crear un mapa de la expresión del (de tipo enum) a (tipo enum)», pero ambos tipos tienen el mismo número de valores y los nombres de cada uno.
    • Para añadir a mi comentario anterior, por extraño que parezca, parece que funciona para uno enum y no de otra. La única diferencia que puedo ver es el que no funciona tiene distintos valores (es decir, ha especificado los valores 1, 2, 4, 9 y no 1, 2, 3, 4).
    • Oh, wow, lo siento por el comentario diluvio, pero al parecer el error fue causado por algo más, algo parecido a la github.com/AutoMapper/AutoMapper/issues/280 . Después de la creación de la enumeración mapa, tengo el «Argumento de los tipos no coinciden», encontró el problema que conlleva hacer dijo enum propiedad que acepta valores null. Entonces me acabo de enterar que en realidad podía quitar la costumbre de la enumeración de asignación. Muy extraño, pero en caso de que alguien encuentra la misma cosa espero que este comentario va a ayudar.
    • Alguien puede dar un ejemplo de lo que esta respuesta está tratando de retratar?

  2. 58

    Como alternativa a la escritura de convertidores personalizados, sólo tiene que utilizar ConvertUsing()

    Mapper.CreateMap<EnumSrc, EnumDst>().ConvertUsing(value => 
    {
        switch(value)
        {
            case EnumSrc.Option1:
                return EnumDst.Choice1;
            case EnumSrc.Option2:
                return EnumDst.Choice2;
            case EnumSrc.Option3:
                return EnumDst.Choice3;
            default:
                return EnumDst.None;
        }
    });
    • Yo estaba usando ConstructUsing y que de alguna manera estaba devolviendo el mal enum a pesar de que mi código era un gigante de instrucción de cambio de devolver el derecho de enumeración. El uso de ConvertUsing se ha solucionado el problema.
    • Este debe ser marcada como la mejor respuesta.
    • Si lo intento, me sale un A lambda expression with a statement body cannot be converted to an expression tree error… El enfoque es grande, aunque.
  3. 10

    Mi Automapper funciona de esta manera:

    Si puedo crear un mapa:
    Automapper coincidirá con las enumeraciones, por su valor, incluso si el nombre coincide perfectamente.

    Si yo no crear un mapa:
    Automapper coincidirá con las enumeraciones por su nombre.

  4. 4

    La Forma más sencilla que he encontrado que funciona para mí es la siguiente:

    Mi Enum es un anidada en otra clase, así que Uso ForMember método y MapFrom de la siguiente manera:

     Mapper.CreateMap<ProblematicCustomer, ProblematicCustomerViewModel>()                
                .ForMember(m=> m.ProblemType, opt=> opt.MapFrom(x=> (ProblemTypeViewModel)(int)x.ProblemType))
                .ForMember(m=> m.JudgmentType, opt=> opt.MapFrom(x=> (JudgmentTypeViewModel)(int)x.JudgmentType));

    La ProblemType y JudgmentType son las Enumeraciones. Y de sus correspondientes Modelos de Vista son ProblemTypeViewModel y JudgmentTypeViewModel con los miembros de la misma como de sus correspondientes Modelos.

    Aunque no tengo pruebas, Pero creo que por debajo de la línea debe trabajar para usted:

    Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>()
               .ForMember(m=> m, opt => opt.MapFrom(x=> (Common.ValidationResultType)(int)x);

    Espero que sea de Ayuda.

  5. 3

    He aquí una posibilidad de hacer una conversión entre dos tipos de Enumeración que ambos tienen diferentes valores, mientras que sigue utilizando AutoMapper. En mi caso, tuve que usar AutoMapper porque los tipos Enum eran las propiedades de otras entidades que están siendo convertidos por AutoMapper; el uso de AutoMapper para estas entidades era un requisito.

    El primer paso es configurar el Asignador de configuración así:

    Mapper.CreateMap<EnumSrc, EnumDst>()
        .ConstructUsing(EnumConversion.FromSrcToDst);

    Llamar .ConstructUsing(...) nos permite pasar en nuestro propio método para hacer la conversión. El método de conversión es muy sencillo:

    public class EnumConversion
    {
        internal static EnumDst FromSrcToDst(ResolutionContext arg)
        {
            EnumSrc value = (EnumSrc)arg.SourceValue;
            switch(value)
            {
                case EnumSrc.Option1:
                    return EnumDst.Choice1;
                case EnumSrc.Option2:
                    return EnumDst.Choice2;
                case EnumSrc.Option3:
                    return EnumDst.Choice3;
                default:
                    return EnumDst.None;
            }
        }
    }

    Simplemente switch a través de los valores de la fuente de la Enumeración y de retorno al destino apropiado valor de Enumeración de forma arbitraria. AutoMapper se encarga del resto.

    • He probado esta aplicación y que sólo se asignan basándose en el valor entero (AutoMapper 3.3.1). Voy a añadir a mi respuesta que trabajó a continuación
  6. 3

    Acaba de crear un mapper para dos Enumeraciones, que es! Automapper se asignarán por el bien de la coincidencia de valor o índice de valor de la Enumeración. (por ejemplo, el Proyecto de -> Paso 1)

    public enum SourceStatus
    {
        Draft,
        Submitted,
        Deleted
    }
    
    public enum DestinationStatus
    {
        Step1,
        Step2,
        Step3
    }
    
    public class SourceObj
    {
        public SourceStatus Status { get; set; }
    }
    
    public class DestinationObj
    {
        public DestinationStatus Status { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            //Static APi style - this is obsolete now. From Version 5.0 onwards    this will be removed.
            SourceObj mySrcObj = new SourceObj();
            mySrcObj.Status = SourceStatus.Deleted;
    
            Mapper.CreateMap<SourceStatus, DestinationStatus>();
            Mapper.CreateMap<SourceObj, DestinationObj>();
    
            DestinationObj myDestObj = Mapper.Map<SourceObj, DestinationObj>(mySrcObj);
    
            //New way of doing it
            SourceObj mySrcObj2 = new SourceObj();
            mySrcObj2.Status = SourceStatus.Draft;
    
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<SourceObj, DestinationObj>();
            });
    
            IMapper mapper = config.CreateMapper();
            var source = new SourceObj();
            var dest = mapper.Map<SourceObj, DestinationObj>(source);
    
    
    
        }
    }
    • Enumeración de asignación como este es muy peligroso. Sabes lo que pasa cuando un tipo tiene números y el otro no tiene número? Se pone REKT, no sé por qué, pero simplemente no funciona, especialmente si queremos tener un nulo valor por defecto.
  7. 3

    Las otras respuestas aquí no funciona para mí.

    Usted necesita para crear una clase que implementa:

    ITypeConvertor<SourceType ,DestinationType>

    Así como un ejemplo

     Mapper.CreateMap<EnumType1.VatLevel, EnumType2.VatRateLevel>()
           .ConvertUsing(new VatLevelConvertor());

    Y la clase:

    internal class VatLevelConvertor : ITypeConverter<EnumType1.VatLevel, EnumType2.VatRateLevel>
    {
        public EnumType2.VatRateLevel Convert(ResolutionContext context)
        {
            EnumType1.VatLevel value = (EnumType1.VatLevel)context.SourceValue;
            switch (value)
            {
                case EnumType1.VatLevel.Standard:
                    return EnumType2.VatRateLevel.Normal;
                case EnumType1.VatLevel.Reduced:
                    return EnumType2.VatRateLevel.Lower;
                case EnumType1.VatLevel.SuperReduced:
                    return EnumType2.VatRateLevel.Other;
                default:
                    return EnumType2.VatRateLevel.Other;
            }
        }
    }
  8. 2

    Yo estaba tratando de mapa entre «iguales» enumeraciones utilizando Automapper, pero lamentablemente no funcionó. Sospecho que el problema es la diferencia de la carcasa:

    public enum Foo {
        val1,
        val2
    }
    
    public enum Bar {
        Val1,
        Val2
    }

    Foo es algo auto-generados a partir de un XSD, y el proveedor de mierda. También hay treinta-algo que los valores de y yo no quiero poner un switch que gran lugar para algo tan tonto.

    El enfoque que tomó fue la de convertir el valor de origen de la cadena y de análisis que, como el valor de destino:

    static Foo ConvertEnum(Bar source)
    {
        Foo result;
        var parsed = Enum.TryParse(source.ToString().ToLowerInvariant(), true, out result);
        if(!parsed)
             //throw or return default value
             throw new ArgumentOutOfRangeException("source", source, "Unknown source value");
        return result;
    }

    Por supuesto, esto sólo funciona si su enumeraciones sólo tienen diferencias en la carcasa. Se podría hacer más elaborado por la limpieza de la cadena de entrada (por ejemplo, quitar subraya etc.) o agregando cosas a como se requiera.

Dejar respuesta

Please enter your comment!
Please enter your name here