未在嵌套集合内映射的自动映像无法正常工作

时间:2015-10-17 08:16:05

标签: c# automapper automapper-4

全部。例如,我们有这样简单的类

public class SimpleModel
{
    public int PropertyId { get; set; }

    public ICollection<SimpleModelCollectionItem> SimpleCollection { get; set; }
}

public class SimpleModelCollectionItem
{
    public int PropertyId { get; set; }
}

public class SimpleEntity
{
    public int Id { get; set; }
    public int PropertyId { get; set; }

    public virtual ICollection<SimpleEntityCollectionItem> SimpleCollection { get; set; }
}

public class SimpleEntityCollectionItem
{
    public int Id { get; set; }
    public int PropertyId { get; set; }
}

我们有一些配置代码

AutoMapper.Mapper.CreateMap<SimpleModel, SimpleEntity>()
            .ForMember(dest => dest.Id, src => src.Ignore())
            .ForMember(dest => dest.SimpleCollection, src => src.UseDestinationValue());

        AutoMapper.Mapper.CreateMap<SimpleModelCollectionItem, SimpleEntityCollectionItem>()
            .ForMember(dest => dest.Id, src => src.Ignore());

        AutoMapper.Mapper.AssertConfigurationIsValid();

并测试数据初始化

            var model = new SimpleModel
                        {
                            PropertyId = 2,
                            SimpleCollection =
                                new List<SimpleModelCollectionItem>
                                    {
                                        new SimpleModelCollectionItem
                                            {
                                                PropertyId = 7
                                            }
                                    }
                        };
        var entity = new SimpleEntity
                         {
                             Id = 1,
                             PropertyId = 3,
                             SimpleCollection =
                                 new List<SimpleEntityCollectionItem>
                                     {
                                         new SimpleEntityCollectionItem
                                             {
                                                 Id = 5,
                                                 PropertyId = 4
                                             }
                                     }
                         };
        AutoMapper.Mapper.Map(model, entity);

我希望看到

Console.WriteLine(entity.Id); // 1
Console.WriteLine(entity.PropertyId); // 2
Console.WriteLine(entity.SimpleCollection.First().Id); // 5 but was 0
Console.WriteLine(entity.SimpleCollection.First().PropertyId); // 7

是否可以将内部集合的Id设置为最初的5?

1 个答案:

答案 0 :(得分:1)

因此,当AutoMapper映射您的集合时,它实际上从目标集合中删除了旧项目,然后添加了一个新项目。

您可以使用以下代码进行验证:

item_same_references

false的值为src => src.UseDestinationValue()

即使您使用的是Id,也会发生这种情况。使用它只意味着它应该重用它自己的集合对象,而不是该集合中的项目。

我不确定是否有办法让AutoMapper也使用相同的收藏品。

另外,考虑一下,如果目标集合包含的项目比源集合少,会发生什么?

因此,您获得的零是因为当AutoMapper创建要添加到集合的新项目时,default(int)属性的默认值为AutoMapper.Mapper.CreateMap<SimpleModel, SimpleEntity>() .ForMember(dest => dest.Id, opt => opt.Ignore()) .ForMember(dest => dest.SimpleCollection, opt => opt.Ignore()); 为零。

我建议如下:

我假设源集合和目标集合中的项目数相等。

首先,修改映射配置以指示AutoMapper忽略这样的集合:

public void MapCollectionsInPlace<TSource, TDestination>(IEnumerable<TSource> source_collection,
    IEnumerable<TDestination> destination_collection)
{
    var source_enumerator = source_collection.GetEnumerator();
    var destination_enumerator = destination_collection.GetEnumerator();

    while (source_enumerator.MoveNext())
    {
        if(!destination_enumerator.MoveNext())
            throw new Exception("Source collection has more items than destination collection");

        AutoMapper.Mapper.Map(source_enumerator.Current, destination_enumerator.Current);
    }
}

然后,创建一个这样的方法,将集合项映射到位(不删除然后添加新项),如下所示:

AutoMapper.Mapper.Map(model, entity);

MapCollectionsInPlace(model.SimpleCollection, entity.SimpleCollection);

现在,您可以使用以下代码:

x = 'id_1'
d = {'id_1':1, 'id_2':2}
print d[x]