簡體   English   中英

使用自動映射器時將源列表中的所有項目返回到 map 到現有列表

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

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