web-dev-qa-db-ja.com

マッピングされているメンバーを除くすべての宛先メンバーを無視する方法は?

これを行う方法はありますか? 3つの異なるタイプからマップするSummaryDtoがあり、各タイプのマップを作成すると、マップされていない小道具がエラーをスローします。サマリーdtoには約35の属性があります。それぞれにIgnore()オプションを使用するのは、面倒です。グローバルな無視はありますか?何かのようなもの

CreateMap<Source,Target>()
   .IgnoreAllUnmapped();
63
epitka

これは私のために働いています:

_public static class MappingExpressionExtensions
{
    public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
    {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}
_

ForAllMembersvoidを返すため、この拡張メソッドなしでForAllMembers(o => o.Ignore())を呼び出しても機能しません。後続のマッピングを有効にするために、マッピング式を使用可能にしておきます。

_CreateMap<Source, Destination>()
            .IgnoreAllUnmapped()
            .ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
            .ForMember(d => d.Value, o => o.MapFrom(s => s.Id));
_
116
CodeMonkeyKing

私もこれにかなり長い間苦労しましたが、少なくともこれに似た問題がありました。多くのプロパティ(約30)を持つクラスがあり、そのうちの4つだけをマップしたかったのです。 26個の無視ステートメントを追加するのはおかしいようです(特に、クラスの将来の変更がそれらの更新を必要とすることを意味する場合!)

最終的に、すべてを無視するようにAutoMapperに指示し、必要なものを明示的に追加できることがわかりました。

// Create a map, store a reference to it in a local variable
var map = CreateMap<Source,Target>();

// Ignore all members
map.ForAllMembers(opt => opt.Ignore());

// Add mapping for P1
map.ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

// Add other mappings...
map.ForMember(dest => dest.P2, opt => opt.MapFrom( src => src.P2));
map.ForMember(dest => dest.P3, opt => opt.MapFrom( src => src.P3));
map.ForMember(dest => dest.P4, opt => opt.MapFrom( src => src.P4));

あなたはこれを行うことができると考えるのは許されます(しかし、コンパイルできないのでそうしないでください):

// This won't compile
CreateMap<Source,Target>()
   .ForAllMembers(opt => opt.Ignore())
   .ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

これが機能しない理由は、ForAllMembers()メソッドが流なスタイルのチェーンをサポートしていないためです(少なくとも現在のバージョン2.0では)。

良いニュースは、非チェーンバージョンが実際に機能することです。もちろん、1つの注意点は、マッピングするメンバーをAutoMapperに明示的に指示する必要があることです。暗黙のマッピングを使用し、破損したマッピングを無視できるように、両方の方法を使用する簡単な方法をまだ見つけていません。

30
Nicholas Green

マップされたプロパティを明示的に指定する必要を回避するには、 IgnoreAllNonExisting を使用できます。ソースプロパティがマップされていない宛先プロパティは無視されます。

5
Edward Brey

あなたの場合、.ConvertUsing()を使用してみてください。

CreateMap<Source,Target>()
 .ConvertUsing(converter=> new Target(){
P1 = converter.P1,
....
});

そのため、オブジェクトに含めるすべてのプロパティを記述できますが、その他は無視されます。

1

ForAllMembersメソッドの流な構文を可能にする拡張メソッド:

public static IMappingExpression<TSource, TDestination> IgnoreAllMembers<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> expression
    )
{
    expression.ForAllMembers(opt => opt.Ignore());
    return expression;
}

使用法:

IgnoreAllMembersの呼び出しは、ForMemberの呼び出しの前でなければなりません。

        CreateMap<LocationRevision, Dto.LocationAddressMap>()
            .IgnoreAllMembers()
            .ForMember(m => m.LocationId, opt => opt.MapFrom(src => src.Id))
            ;
1
Casey