web-dev-qa-db-ja.com

空のコレクションを返すオートマッパー、nullが必要

public class Person
{
   Name { get; set; }
   IEnumerable<Address> Addresses { get; set; }
}

public class PersonModel
{
   Name { get; set; }
   IEnumerable<AddressModel> Addresses { get; set; }
}

PersonPersonModelにマップすると、次のようになります。

Mapper.DynamicMap<Person, PersonModel>(person);

AddressesPersonプロパティがnullの場合、それらはPersonModelにnullではなく空のEnumerableとしてマップされます。

空のPersonModelではなくAddressesにnull Enumerableを持たせるにはどうすればよいですか?

21
c0D3l0g1c

したがって、Automapperを使用してこれを実現する方法はおそらくいくつかあり、これは1つにすぎません。

Mapper.CreateMap<Person, PersonMap>()
   .AfterMap( (src, dest) => dest.Addresses = dest.Addresses?.Any() ? dest.Addresses : null );

このコードはnullの安全性のために新しいc#?.演算子を使用しているため、コードでその機能を使用できない場合は、それを削除してnullを確認する必要がある場合があります。

12
CodingGorilla

単純な答えはAllowNullCollectionsを使用することです:

AutoMapper.Mapper.Initialize(cfg =>
{
    cfg.AllowNullCollections = true;
});

またはインスタンスAPIを使用する場合

new MapperConfiguration(cfg =>
{
    cfg.AllowNullCollections = true;
}
39
Kirill Rakhman

マッパー構成の初期化AllowNullCollectionsを設定することに加えて( この答え で注記されているように)、AllowNullCollectionsを設定するオプションがありますProfileの定義は次のようになります。

public class MyMapper : Profile
{
    public MyMapper()
    {
        // Null collections will be mapped to null collections instead of empty collections.
        AllowNullCollections = true;

        CreateMap<MySource, MyDestination>();
    }
}
6
Mike

これのもう1つの方法は、条件を使用することです。そのため、値がnullでない場合にのみ値をマップします。これには、値がデフォルトでnullである必要がある場合があります(マッピングされないため)。

 Mapper.CreateMap<Person, PersonModel>()
.ForMember(
    dest => dest.Addresses,
    opt => opt => opt.Condition(source=> source.Addresses!= null));
2
PJUK

この動作が必要なプロパティのカスタムリゾルバーを定義できるはずです。だから次のようなもの:

Mapper.CreateMap<Address, AddressModel>();
Mapper.CreateMap<Person, PersonModel>()
    .ForMember(
        dest => dest.Addresses,
        opt => opt.ResolveUsing(person => person.Addresses.Any() ? person.Addresses.Select(Mapper.Map<Address, AddressModel>) : null));
1
Ben