Automapper: UseDestinationValue does not work for collections?

不羁的心 提交于 2021-02-11 13:40:57

问题


Let's assume there are classes:

public class Foo
{
    public List<Bar> Bars { get; set; }
}

public class Bar
{
    public string Name { get; set; }
    public string Description { get; set; }
}

public class FooDto
{
    public List<BarDto> Bars { get; set; }
}

public class BarDto
{
    public string Name { get; set; }
}

public class MapperProfile : Profile
{
    public MapperProfile()
    {
        CreateMap<FooDto, Foo>();
        CreateMap<BarDto, Bar>()
            .ForMember(dest => dest.Description, opt => opt.UseDestinationValue());
    }
}

If I'm using one-to-one mapping, everything is working as expected:

var mapper = new Mapper(new MapperConfiguration(e => e.AddProfile(typeof(MapperProfile))));

var bar = new Bar
{
    Name = "name",
    Description = "description"
};

var barDto = new BarDto
{
    Name = "updated name"
};

mapper.Map(barDto, bar);

Console.WriteLine(bar.Name);
Console.WriteLine(bar.Description);

// Output:
// updated name
// description

But this is not working for collections:

var mapper = new Mapper(new MapperConfiguration(e => e.AddProfile(typeof(MapperProfile))));

var foo = new Foo
{
    Bars = new List<Bar>
    {
        new Bar
        {
            Name = "name",
            Description = "description",
        }
    }
};

var fooDto = new FooDto
{
    Bars = new List<BarDto>
    {
        new BarDto
        {
            Name = "updated name"
        }
    }
};

mapper.Map(fooDto, foo);

foreach (var bar in foo.Bars)
{
    Console.WriteLine(bar.Name);
    Console.WriteLine(bar.Description);
}

// Output:
// updated name
//                

Bar's Description is null after mapping (have tested on 9.0.0 and 10.0.0 versions).

What is the reason, how to fix?


回答1:


Finally, I have found the solution. Automapper clears the destination collection before mapping, that is why all properties are set to default. AutoMapper.Collection can helps in this case.

public class Foo
{
    public List<Bar> Bars { get; set; }
}

public class Bar
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

public class FooDto
{
    public List<BarDto> Bars { get; set; }
}

public class BarDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MapperProfile : Profile
{
    public MapperProfile()
    {
        CreateMap<FooDto, Foo>();
        CreateMap<BarDto, Bar>()
            .EqualityComparison((src, dest) => src.Id == dest.Id);
    }
}


And using like this:

var mapper = new Mapper(new MapperConfiguration(e =>
{
    e.AddCollectionMappers();
    e.AddProfile(typeof(MapperProfile));
}));

var foo = new Foo
{
    Bars = new List<Bar>
    {
        new Bar
        {
            Id = 1,
            Name = "name",
            Description = "description",
        }
    }
};

var fooDto = new FooDto
{
    Bars = new List<BarDto>
    {
        new BarDto
        {
            Id = 1,
            Name = "updated name"
        }
    }
};

mapper.Map(fooDto, foo);

foreach (var bar in foo.Bars)
{
    Console.WriteLine(bar.Name);
    Console.WriteLine(bar.Description);
}

// Output:
// updated name
// description


来源:https://stackoverflow.com/questions/62747877/automapper-usedestinationvalue-does-not-work-for-collections

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!