[英]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.