2017-01-12 8 views
0

2つのエンティティをマップしようとしています。 1つは文字列のリストを持ち、もう1つはカスタムコレクションを使用しています。オートマッパーを使ってこれらの2つのエンティティをどのようにマップすることができますか?ここでAutomapper CustomCollectionへのリスト

public class SourceItem 
{ 
    public string Name { get; set; } 

    public List<string> ShipsTo { get; set; } 
} 

public class DestItem 
{ 
    public string Name { get; set; } 

    public MyCollection ShipsTo { get; set; } 
} 

public class MyCollection : CollectionBase 
{ 
    private readonly List<string> _list; 

    public MyCollection() 
    { 
     _list = new List<string>(); 
    } 

    public MyCollection(List<string> list) 
    { 
     _list = list; 
    } 

    public void Add(string item) 
    { 
     _list.Add(item); 
    } 
} 

私のマッピングコードはここ

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<SourceItem, DestItem>() 
    .ForMember(d => d.ShipsTo, o => o.ResolveUsing<CustomResolver>()); 
}); 

は私のカスタムリゾルバが

私はこのコードを実行しようとすると、私が取得
public class CustomResolver : IValueResolver<SourceItem, DestItem, MyCollection> 
{ 
    public MyCollection Resolve(SourceItem source, DestItem destination, MyCollection destMember, ResolutionContext context) 
    { 
     return new MyCollection(source.ShipsTo); 
    } 
} 

...どのように見えるかです...ですエラーが発生しました

型の間で強制演算子が定義されていません 'System.Collections.Generic.List`1 [System.Object]'および 'MyCollection'。

本当にありがとうございます。

+0

Automapperにはバグがあります。しかし、とにかく、なぜCollectionBaseを継承する必要がありますか? –

+0

@SergeyBerezovskiyこれは一例です。実際に私はサードパーティのAPI(eBay SDK)を使用していますが、私が投稿した例のようにCollectionBaseを使用しているコレクションがたくさんあります。カスタムコレクションを変更することはできません。 – nafr1

答えて

0

あなたはMyCollectionからMyCollectionに明示的なマッピングの設定を定義した場合、私は本当にそれを説明することができませんでしたが、それは動作します:

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<MyCollection, MyCollection>().ConvertUsing((a,b)=>a); 

    cfg.CreateMap<SourceItem, DestItem>() 
      .ForMember(d => d.ShipsTo, o => o.ResolveUsing<CustomResolver>()); 
}); 

私は理由を見つけるためにautomapperのコードをデバッグしています。理由は、AutomapperはMyCollectionMyCollectionにマップするのに適したマッパーを探しています。すべてのマッパー(あなたの設定で定義され、定義済み)のコレクションを探します。実際には、それは何を見つけるべきであるAssignableMapper、ちょうど別の1つの変数を割り当てるが、まず彼はEnumerableMapperをチェックし、あなたのCollectionBaseEnumerableですので、それは大丈夫と思われる。このEnumerableMapperの例外は、この2つのコレクションをマップできなかったためです。解決策は、ある変数を別の変数に割り当てる必要があることを明示的に定義することです。

enter image description here

しかし。私はSergeyに同意します。これはいくつかの醜いバグです、私が示唆しているのは全く同じ醜い回避策です。答えは

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<SourceItem, DestItem>() 
    .ForMember(d => d.ShipsTo, o => o.MapFrom(src => new MyCollection(src.ShipsTo))); 
}); 
+0

エラーは消えますが、マッピングがありません - MyCollectionが空です –

+0

@SergeyBerezovskiy私は答えを変更しました。 –

+0

推奨されるコードではエラーは発生しませんが、MyCollectionはまだ空です。 .ForMemberを実行しても(d => d.ShipsTo、o => o.MapFrom(src => new MyCollection(src.ShipsTo))); – nafr1

0

を動作させるためにこれをしようと管理していますバグがあります(私はbacklogに項目を追加しました。あなたはそれを追跡できます)。しかし、ジミーが提案したように、List<string>MyCollectionの間の変換を指定することができます。そして、すべて正常に動作します:

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<List<string>, MyCollection>().ConvertUsing(s => new MyCollection(s)); 
    cfg.CreateMap<SourceItem, DestItem>(); 
}); 

BTWすでに問題は修正されているようで、Automapperの次のリリースで利用できるはずです。

+0

あなたは正しいと思いますが、彼は例外を避けるためにカスタムリゾルバーを書いていました。あなたもあなたのコードでそれを得るでしょう。 –

0

:あなたはので、ここではカスタム値リゾルバを使用することはできませんが、私は、私はあなたがカスタムリゾルバを必要としていることがわかりません、それは:)

関連する問題