けさらんぱさらん

方向性は定めず、ただ思いつくままに

AutoMapperではまった件

また間が空いてしまった。
継続できないマンです。

ちょっとAutoMapperではまったことをメモっておきます。
AutoMapperは、簡単な設定で異なるクラスのオブジェクトをマップしてくれる便利なライブラリです。

こんな感じ

Mapper.CreateMap<Custormer, CustomerDTO>();
var dto = Mapper.Map<Custormer, CustomerDTO>(new Custormer { Id = 1 });

これだけでCustomerDTOのIdプロパティに1が代入されます。
ちなみにCreateMapメソッドはアプリケーションの中で一度呼べばOKです。
処理ごとに呼ぶと遅くなるので注意。
これも知らなくてはまったわけですが・・・

例えばCustomerクラスはこんな構造です。

class Custormer
{
    public int Id { get; set; }
    public Name Name { get; set; }
}

Customerクラスが持っているNameクラスはこんな感じ

class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

そしてMapされる側のCustomerDTOはこんな感じ

class CustomerDTO
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

持っている情報は同じですが多少構造が異なります。
こうゆう場合AutoMaperでは

Mapper.CreateMap<Custormer, CustomerDTO>()
    .ForMember(t => t.FirstName, m => m.MapFrom(s => s.Name.FirstName))
    .ForMember(t => t.LastName, m => m.MapFrom(s => s.Name.LastName));

このようにMapの設定を明示的に記述します。
これでMapメソッドを呼べば無事名前もDTOに代入されます。
簡単ですね。

ただこれがNameプロパティがnullだったときに問題が発生します。
例外はでませんが処理がかなり遅くなります。
なかなかこの問題に気づかずに悩んでました。

これを解決するには、まあnullチェック入れろってことなんですかねー

Mapper.CreateMap<Custormer, CustomerDTO>()
    .ForMember(t => t.FirstName, m => m.MapFrom(s => s.Name == null ? String.Empty : s.Name.FirstName))
    .ForMember(t => t.LastName, m => m.MapFrom(s => s.Name == null ? String.Empty : s.Name.LastName));

これで手元では6倍くらい速くなりました。