繁体   English   中英

如何使用 Automapper 在目标 object 中保留集合的未映射属性?

[英]How to preserve the not mapped properties of a collection in a destination object with Automapper?

初始情况:我有一个源和一个目标 object 并且都有一个Elements集合。 使用 Automapper I map 从源到目标 object。之后,我将信息添加到仅存在于目标 object( ItemNameItemNumber )上的属性。 此外,我将信息添加到集合AssetElementDto中对象的属性Text 之后,我调用mapper.Map(source_update, destination); 更新目的地 object。

问题:当我运行代码时,更新后保留了ItemNameItemNumber的信息。 我该怎么做才能保留TextAssetElementDto信息?

using AutoMapper;
using System.Runtime.InteropServices;

public class Program
{
    static void Main(string[] arg)
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Source, Destination>().PreserveReferences();
            cfg.CreateMap<AssetElement, AssetElementDto>().PreserveReferences();
        });
        var mapper = new Mapper(config);

        var source = new Source()
        {
            Name = "Sinonis",
            Id = new Random().Next(),
            Elements = new List<AssetElement>
            {
                new(){ Id = 1},
                new(){ Id = 2}
            }
        };

        var destination = mapper.Map<Destination>(source);
        destination.ItemNumber = 42;
        destination.Elements.ForEach(e => e.Text ="Wow");

        destination.ItemName = "NPC21";

        var source_update = new Source()
        {
            Name = "Nindalf",
            Id = new Random().Next(),
            Elements = new List<AssetElement>
            {
                new(){ Id = 3},
                new(){ Id = 4}
            }
        };

        Console.WriteLine($"Before update is: {destination.Name} {destination.Id} {destination.ItemNumber} {destination.ItemName}");
        destination.Elements.ForEach(e => Console.WriteLine($" {e.Id} {e.Text}"));

        mapper.Map(source_update, destination);

        Console.WriteLine($"After update is : {destination.Name} {destination.Id} {destination.ItemNumber} {destination.ItemName}");
        destination.Elements.ForEach(e => Console.WriteLine($" {e.Id} {e.Text}"));
    }
}

#region Source

public class Source
{
    public string Name;
    public int Id;

    public List<AssetElement> Elements;

}

public class AssetElement
{
    public int Id;
}

#endregion

#region Destination

public class Destination
{
    public string Name;
    public int Id;

    public List<AssetElementDto> Elements;

    public int ItemNumber;
    public string ItemName;
}

public class AssetElementDto
{
    public string Text;
    public int Id;
}

#endregion

控制台 Output:

更新后Wow没有保留。

Before update is: Sinonis 1643275093 42 NPC21
 1 Wow
 2 Wow
After update is : Nindalf 75522068 42 NPC21
 3 null
 4 null

感谢Lucian Bargaoanu提供的这个简短而有力的提示。 这解决了我的问题。 请在下面的代码中查看必要的更改。 这是 AutoMapper.Collection 的链接

using AutoMapper;
using AutoMapper.EquivalencyExpression; //add using

public class Program
{
    static void Main(string[] arg)
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddCollectionMappers(); //add the collection mapper
            cfg.CreateMap<Source, Destination>();
            cfg.CreateMap<AssetElement, AssetElementDto>().EqualityComparison((odto, o) => odto.Id == o.Id); //add the equality compersion
        });
        var mapper = new Mapper(config);

        var source = new Source()
        {
            Name = "Sinonis",
            Id = new Random().Next(),
            Elements = new List<AssetElement>
            {
                new(){ Id = 1},
                new(){ Id = 2}
            }
        };

        var destination = mapper.Map<Destination>(source);
        destination.ItemNumber = 42;
        destination.ItemName = "NPC21";
        destination.Elements.ForEach(e => e.Text ="Wow");

       

        var source_update = new Source()
        {
            Name = "Nindalf",
            Id = new Random().Next(),
            Elements = new List<AssetElement>
            {
                new(){ Id = 1},//ID's need to be the same as before
                new(){ Id = 2}
            }
        };

        Console.WriteLine($"Before update is: {destination.Name} {destination.Id} {destination.ItemNumber} {destination.ItemName}");
        destination.Elements.ForEach(e => Console.WriteLine($" {e.Id} {e.Text}"));

        mapper.Map(source_update, destination);

        Console.WriteLine($"After update is : {destination.Name} {destination.Id} {destination.ItemNumber} {destination.ItemName}");
        destination.Elements.ForEach(e => Console.WriteLine($" {e.Id} {e.Text}"));
    }
}

#region Source

public class Source
{
    public string Name;
    public int Id;

    public List<AssetElement> Elements;

}

public class AssetElement
{
    public int Id;
}


#endregion

#region Destination

public class Destination
{
    public string Name;
    public int Id;

    public List<AssetElementDto> Elements;

    public int ItemNumber;
    public string ItemName;
}

public class AssetElementDto
{
    public string Text;
    public int Id;
}

#endregion

安慰:

更新后Wow保留在合集中。

Before update is: Sinonis 49772274 42 NPC21
 1 Wow
 2 Wow
After update is : Nindalf 236466397 42 NPC21
 1 Wow
 2 Wow

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM