簡體   English   中英

未在嵌套集合中映射的自動映射器無法正常工作

[英]Automapper not mapped inside nested collection is not working properly

所有。 例如我們有這么簡單的類

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?

因此,當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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM