使用AutoMapper复制列表项

时间:2010-12-27 10:44:39

标签: automapper

当我使用List属性映射对象时默认情况下,Automapper将目标对象上的list属性设置为源对象中的实例。

有没有办法让automapper创建新列表并复制项目但不复制列表实例?

我希望通过以下测试:

var widget = new Widget
                {
                    Tags = new List<string> {"big", "bright"}
                };

Mapper.Reset();
Mapper.CreateMap<Widget, Widget>();

var widgetCopy = Mapper.Map<Widget, Widget>(widget);

CollectionAssert.Contains(widgetCopy.Tags, "big");
CollectionAssert.Contains(widgetCopy.Tags, "bright");
Assert.AreNotSame(widget.Tags, widgetCopy.Tags);

小部件类的外观如下:

class Widget
{
    public IList<string> Tags { get; set; }
}

目前最后一个断言失败,因为两个标签属性指向列表的同一个实例。当使用NHibernate持久保存对象时,这是一个问题。

2 个答案:

答案 0 :(得分:3)

您要求的是深度克隆,AutoMapper isn't really designed to do

还有其他选择。看看ValueInjecter是否适合您。

查看Deep cloning with ValueInjecter

答案 1 :(得分:0)

我通过定义这样的扩展方法解决了这个问题:

public static class DeepCopyExtensions
{
    public static List<T> DeepCopy<T>(this List<T> original)
    {
        lock(original) 
            return original.Select(AutoMapper.Mapper.Map<T, T>).ToList();
    }

    public static T DeepCopy<T>(this T original)
    {
        return AutoMapper.Mapper.Map<T, T>(original);
    }
}

并像这样定义我的AutoMapper映射:

Mapper.CreateMap<Widget, Widget>()
    .ForMember(
        dest => dest.Tags,
        opt => opt.MapFrom(src => src.Tags.DeepCopy()));