[英]Return all items in source list when using automapper to map to existing list
我有一個從數據庫加載的對象列表,我們稱它們為“MyObjects”,然后我有一個從單獨數據庫加載的擴展對象“ExtensionsObjects”列表。 我使用自動映射器將這些擴展對象的一些屬性 map 用於“MyObjects”。 (擴展 object 包含 MyObject 的關鍵字段)
這有效,字段從 ExtentionObject 正確映射到 MyObject,但自動映射器返回一個列表,該列表僅返回“ExtensionObject”映射到的那些“MyObjects”。 (而沒有擴展 object 的 MyObject 是完全有效的情況)。
我用於映射的代碼:
//first get the lists of MyObjects and ExtentionObjects
List<MyObject> myObjects = GetMyObjects();
List<ExtentionObject> extentionObjects = GetExtentionObjects();
//execute the mapping (_mapper is my automapper)
myObjects = _mapper.Map(extentionObjects, myObjects);
//myObject now contains less objects than before the call to the mapper
自動映射器配置的代碼(cfg 是用於創建映射器的映射器配置):
cfg.CreateMap<ExtentionObject, MyObject>()
.EqualityComparison((eo, my)=> CheckForEquality(eo, my))
.ForMember(....)
.ForMember(....)
.ReverseMap().ConvertUsing((mo, eo)=>
{
var ext = new ExtentionObect();
...
return ext;
});
相等性檢查 function 僅檢查 ExtentionObject 和 MyObject 的 ID 是否匹配。
我希望結果列表包含原始“myObjects”列表中的所有項目。 ExtentionObject 實例中的信息應添加到相應的 MyObject 實例中,但由於 Extention 是可選的,因此所有“MyObjects”必須保留在結果列表中。
假設我的數據庫包含具有鍵 1、2,3 的 MyObjects 和具有鍵 1 和 3 的 ExtentionObjects。
//before this cal myObjects contains 3 items, ExentionObjects contains 2
myObjects = _mapper.Map(extentionObjects, myObjects);
//after this cal myObjects contains only 2 items,
//with the properties from Extentionobject 1 and 3 correctly mapped to MyObject 1 and 3,
//ERROR => MyObject 2 has "disappeared" from the 'destination' list
問題是“如何將 Object 2 保留在我的列表中”?
經過進一步調查,事實證明問題不在於 Automapper 本身,而在於 Automapper.Collections(automapper 擴展到 map 集合)。 在其github 存儲庫中提出了相同功能的問題,但沒有真正的解決方案。 盡管有關於如何修改 automapper.collection 以避免刪除的建議,但我認為從長遠來看,分叉這個存儲庫並不明智。 然而,對於從列表中刪除項目的位置有一個指示。 它使用 ICollection.Remove() 方法(不明確然后添加值)。
所以我的解決方案是將我的列表包裝在一個“EditOnlyCollection”中,該列表具有“刪除”的“nop”實現。 (在我的情況下,其他方法也有一個“nop”,但這很容易改變)。 注意:它不適用於 ReadOnlyCollection 中的構建,因為它會在 remove 方法中引發異常。
class EditOnlyCollection<T> : ICollection<T>
{
private readonly List<T> list;
public EditOnlyCollection(IEnumerable<T> list)
{
this.list = list.ToList();
}
public int Count => list.Count;
public bool IsReadOnly => true;
public void Add(T item)
{
//nop
}
public void Clear()
{
//nop
}
public bool Contains(T item)
{
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array, arrayIndex);
}
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
public bool Remove(T item)
{
//nop
return true; //have them think we removed an item
}
IEnumerator IEnumerable.GetEnumerator()
{
return list.GetEnumerator();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.