0

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

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?

4

1 回答 1

1

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

您可以使用以下代码验证这一点:

var item_before = entity.SimpleCollection.First();

AutoMapper.Mapper.Map(model, entity);

var item_after = entity.SimpleCollection.First();

bool item_same_references = object.ReferenceEquals(item_before, item_after);

item_same_references的值为false

即使您使用src => src.UseDestinationValue(). 使用它仅意味着它自己的集合对象应该被重用,而不是该集合中的项目。

我不确定是否有办法告诉 AutoMapper 也使用相同的集合项。

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

所以,你得到的零是因为当 AutoMapper 创建新项目以添加到集合中时,Id属性的默认值default(int)是零。

我建议如下:

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

首先,修改您的映射配置以指示 AutoMapper 忽略集合,如下所示:

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

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

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);
于 2015-10-17T18:42:22.803 回答