Pregunta

La clase fuente:

public class Post
{
    public long ID { get; set; }

    [Column(TypeName="nvarchar")]
    [Required]
    [StringLength(250)]
    public string Name { get; set; }

    [Column(TypeName="varchar")]
    [StringLength(250)]
    public string UrlName { get; set; }

    [Column(TypeName="ntext")]
    public string Excerpt { get; set; }

    [Column(TypeName="ntext")]
    [Required]
    public string Content { get; set; }

    public DateTime PostedTime { get; set; }
    public DateTime? PublishedTime { get; set; }
    public DateTime? LastUpdatedTime { get; set; }
    public bool IsPublished { get; set; }

    public virtual List<Category> Categories { get; set; }
    public virtual List<Comment> Comments { get; set; }
    public virtual List<Tag> Tags { get; set; }
}

la clase de destino

public class Post : Model
{
    public long ID { get; set; }
    public string Name { get; set; }
    public string UrlName { get; set; }
    public string Excerpt { get; set; }
    public string Content { get; set; }
    public DateTime PostedTime { get; set; }
    public DateTime LastCommentedTime { get; set; }
    public bool IsPublished { get; set; }

    public List<Category> Category { get; set; }
    public List<Comment> Comments { get; set; }
    public List<Tag> Tags { get; set; }
}

Intento usar emitmapper para mapear entre sí; Al asignar de fuente a descripción, aquí está la muestra de código:

[TestMethod]
    public void ShouleMapEntityToModel()
    {
        Post eP = new Post();
        eP.ID = 2;
        eP.Comments = new List<Comment>();

        eP.Comments.Add(new Comment()
            {
                ID = 2,
                Author = "derek"
            });

        var mP = eP.Map<Post, mBlog.Core.Models.Post>();

        Assert.IsNotNull(mP);
        Assert.AreEqual(1, mP.Comments.Count());
    }

Y tengo una excepción,

Método de prueba mblog.test.emitmappertest.ShoulEmapentityTomodel lanzó excepción: System.Exception: Constructor para tipos [] no encontrados en System.Collections.Generic.ilist`1 [[mblog.core.models.post, mblog.core, versión = 1.0 .0.0, cultura = neutral, public keyToken = null]

¿Fue útil?

Solución

Tuve el mismo problema, pero he encontrado la solución. No sean listas de usuarios para su objeto de destino. Si usa matrices simples en su mblog.core.models.post Object debe obtener un objeto bien lleno. Entonces su clase de destino debería verse como:

public class Post : Model
{
    public long ID { get; set; }
    public string Name { get; set; }
    public string UrlName { get; set; }
    public string Excerpt { get; set; }
    public string Content { get; set; }
    public DateTime PostedTime { get; set; }
    public DateTime LastCommentedTime { get; set; }
    public bool IsPublished { get; set; }

    public Category[] Category { get; set; }
    public Comment[] Comments { get; set; }
    public Tag[] Tags { get; set; }
}

Otros consejos

Esta respuesta muestra cómo manejar IEnumerable para IEnumerable: Emitmapper y lista

Creo que eso también se puede aplicar a este caso. Echar un vistazo:

Esto se puede hacer creando una clase personalizada, implementando la interfaz "iCustomConverterProvider" y agregando un convertGeneric al "defaultMapConfig".

Mirando en el código fuente de EMITMapper, encontré una clase llamada "ArraySconverterProvider", que es el convertidor genérico predeterminado de ICOLLECECIONES a matrices.

Adaptando el código de esta clase para trabajar con IEnumerable Collections:

class GenericIEnumerableConverterProvider : ICustomConverterProvider
    {
      public CustomConverterDescriptor GetCustomConverterDescr(
            Type from,
            Type to,
            MapConfigBaseImpl mappingConfig)
        {
            var tFromTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(from);
            var tToTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(to);
            if (tFromTypeArgs == null || tToTypeArgs == null || tFromTypeArgs.Length != 1 || tToTypeArgs.Length != 1)
            {
                return null;
            }
            var tFrom = tFromTypeArgs[0];
            var tTo = tToTypeArgs[0];
            if (tFrom == tTo && (tFrom.IsValueType || mappingConfig.GetRootMappingOperation(tFrom, tTo).ShallowCopy))
           {
               return new CustomConverterDescriptor
                {
                    ConversionMethodName = "Convert",
                    ConverterImplementation = typeof(GenericIEnumerableConverter_OneTypes<>),
                    ConverterClassTypeArguments = new[] { tFrom }
                };
            }

            return new CustomConverterDescriptor
            {
                ConversionMethodName = "Convert",
                ConverterImplementation = typeof(GenericIEnumerableConverter_DifferentTypes<,>),
                ConverterClassTypeArguments = new[] { tFrom, tTo }
            }; 
        }
    }


class GenericIEnumerableConverter_DifferentTypes<TFrom, TTo> : ICustomConverter
    {
        private Func<TFrom, TTo> _converter;
        public IEnumerable<TTo> Convert(IEnumerable<TFrom> from, object state)
        {
            if (from == null)
            {
                return null;
            } 

            TTo[] result = new TTo[from.Count()];
            int idx = 0;
            foreach (var f in from)
            {
                result[idx++] = _converter(f);
            }

            return result;
        } 

        public void Initialize(Type from, Type to, MapConfigBaseImpl mappingConfig)
        {
            var staticConverters = mappingConfig.GetStaticConvertersManager() ?? StaticConvertersManager.DefaultInstance;

            var staticConverterMethod = staticConverters.GetStaticConverter(typeof(TFrom), typeof(TTo));

           if (staticConverterMethod != null)
            {
                _converter = (Func<TFrom, TTo>)Delegate.CreateDelegate(
                    typeof(Func<TFrom, TTo>),
                    null,
                    staticConverterMethod
                );
            }
            else
            {
                _subMapper = ObjectMapperManager.DefaultInstance.GetMapperImpl(typeof(TFrom), typeof(TTo), mappingConfig);

                _converter = ConverterBySubmapper;
            }
        } 

        ObjectsMapperBaseImpl _subMapper;

        private TTo ConverterBySubmapper(TFrom from)
        {
            return (TTo)_subMapper.Map(from);
        }
    }


class GenericIEnumerableConverter_OneTypes<T>
    {

        public IEnumerable<T> Convert(IEnumerable<T> from, object state)
        {
            if (from == null)
          {
                return null;
            }

            return from;
        }
    }

Este código es solo una copia con un mínimo de adaptación posible y puede aplicarse a objetos con muchos niveles de jerarquía.

Puede usar el código anterior con el siguiente comando:

  new DefaultMapConfig().ConvertGeneric(
    typeof(IEnumerable<>),
    typeof(IEnumerable<>),
    new GenericIEnumerableConverterProvider());

¡Esto me salvó el día y espero salvar el tuyo también! jejeje

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top