C# Automapper 6.1.1 - Collection/List destination

2019-09-16 11:13发布

问题:

I have a problem when mapping collections with Automapper 6 and I can't find a solution. In the updatedArticle object below I have the old Created and Updated values left after mapping since they do not exist on the view model. However the values for Created and Updated in Descriptions are lost. The values that do come in via the view model are all updated correctly. What am I doing wrong? Automapper also loses Entity Framework 6 mapping for Article since those values are lost as well.

Controller method:

public async Task<IHttpActionResult> UpdateArticle(ArticleViewModel articleVm)
{
    Article articleOriginal = await iArticleRepository.GetAsync(articleVm.Id);
    Article updatedArticle = Mapper.Map<ArticleViewModel, Article>(articleVm, articleOriginal);
    return Ok();
}

Mapping:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<ArticleViewModel, Article>()
        .ForMember(x => x.Created, opt => opt.Ignore())
        .ForMember(x => x.Updated, opt => opt.Ignore());

    cfg.CreateMap<DescriptionViewModel, Description>()
        .ForMember(x => x.Created, opt => opt.Ignore())
        .ForMember(x => x.Updated, opt => opt.Ignore())
        .ForMember(x => x.ArticleId, opt => opt.Ignore())
        .ForMember(x => x.Article, opt => opt.Ignore());
}
Mapper.AssertConfigurationIsValid();

Viewmodels:

public class ArticleViewModel
{
    public int Id { get; set; }

    public string Name { get; set; }

    public List<DescriptionViewModel> Descriptions { get; set; }
}

public class DescriptionViewModel
{
    public int Id { get; set; }

    public string Heading { get; set; }
}

Models:

public class Article : IEntity<int>
{
    public Article()
    {
        Descriptions = new List<Description>();
    }

    [Key]
    public int Id { get; set; }

    public DateTime Created { get; set; }

    public DateTime Updated { get; set; }

    [MaxLength(256)]
    public string Name { get; set; }

    public virtual ICollection<Description> Descriptions { get; set; }
}

public class Description: IEntity<int>
{
    [Key]
    public int Id { get; set; }

    public DateTime Created { get; set; }

    public DateTime Updated { get; set; }

    [MaxLength(256)]
    public string Heading { get; set; }

    public int ArticleId { get; set; }

    public virtual Article Article { get; set; }
}

回答1:

Have you tried this without lazy loading? I had some issues with EF Lazy Loading and AutoMapper myself. First of all it is very inefficient.

See related Answer.



回答2:

Finally solved it after two days frustration. Installed AutoMapper.Collection from https://github.com/AutoMapper/AutoMapper.Collection

PM> Install-Package AutoMapper.Collection
PM> Install-Package AutoMapper.Collection.EntityFramework

All I had to change was cfg.AddCollectionMappers(); and EqualityComparison. Example:

Mapper.Initialize(cfg =>
{
    cfg.AddCollectionMappers();

    cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();

    cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
        .EqualityComparison((src, dst) => src.Id == dst.Id);

    cfg.CreateMap<DescriptionViewModel, Description>(MemberList.Source)
        .EqualityComparison((src, dst) => src.Id == dst.Id);
}
Mapper.AssertConfigurationIsValid();