Automapperで1つのプロパティのマッピングを無視する


285

Automapperを使用していて、次のシナリオがあります。クラスOrderModelに、データベースにない 'ProductName'というプロパティがあります。だから私がマッピングをしようとすると:

Mapper.CreateMap<OrderModel, Orders>(); 

それは例外を生成します:

「Project.ViewModels.OrderModelの次の1つのプロパティはマップされていません: 'ProductName'

AutoMapperのWiki for Projectionsで逆のケースを読んだことがあります(追加の属性は宛先にあり、実際には私の場合のソースにはありません)。

オートマッパーがこのプロパティのマッピングを作成しないようにするにはどうすればよいですか?


7
Automapperはそのようには機能しません。宛先オブジェクトのプロパティのみに関係します。srcには100の追加プロパティを含めることができます-Automapperはdestプロパティのみをマップします。マッピングの例外を引き起こしている何かが他にあるに違いありません。機能していないもののコードを投稿できますか?
PatrickSteele、

それはあなたが自動的に尋ねるものをします。明確にするためにいくつかのコードを投稿してください
BeRecursive

次の記事を見て、これらはあなたが役立つかもしれないstackoverflow.com/questions/4456519/... stackoverflow.com/questions/4052579/...
ディビ

3
@Patrick AutoMapperは、メソッド/プロパティ名の分析でいくつかのトリックを実行します。宛先に完全に一致していない場合でも、意図せずにマップされているソース上のプロパティがある可能性があります。これが発生したときにこれを防ぐためのForSourceMember(... Ignore())があるのはこのためです。
AaronLS

回答:


477

ジミー・ボガードから: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

それは彼のブログのコメントの1つにあります


13
また、CreateMap<Foo, Bar>().ForSourceMember(x => x.Blarg, opt => opt.Ignore());役に立つかもしれません
stackoverfloweth 2018

5
@stackoverflowethどういう意味CreateMap<SourceType, DestType> (MemberList.Source).ForSourceMember(x => x.MySourceProperty, opt => opt.DoNotValidate())ですか?
モンティ

12
無視ForSourceMemberにDoNotValidateに置き換えられました:github.com/AutoMapper/AutoMapper/blob/master/docs/...
ジェイミー・

@Jamie @monty-私はこのre:コメントを更新し始めましたが、構文の変更はプロジェクションのケースのみに影響するようです(ソースプロパティを無視する必要がある場合)。OPの要求は宛先プロパティを無視することなので、Ignore()正しい構文のままです。これは、の構文変更IgnoreISourceMemberConfigurationExpressionインターフェイスで行われたが、分離したインターフェイスでは行われなかったためIMemberConfigurationExpression`3です。
smartcaveman

2
@Franva ForMember()は実際には "ForDestinationMember()"です
rvnlord

243

たぶん私は少し完璧主義者です。ForMember(...、x => x.Ignore())構文はあまり好きではありません。それは小さなことですが、私にとってそれは重要です。私はそれを少し良くするためにこの拡張メソッドを書きました:

public static IMappingExpression<TSource, TDestination> Ignore<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> map,
    Expression<Func<TDestination, object>> selector)
{
    map.ForMember(selector, config => config.Ignore());
    return map;
}

次のように使用できます。

Mapper.CreateMap<JsonRecord, DatabaseRecord>()
        .Ignore(record => record.Field)
        .Ignore(record => record.AnotherField)
        .Ignore(record => record.Etc);

で動作するように書き換えることもできparamsますが、ラムダをロードするメソッドの外観は好きではありません。


6
私はこれが最初の質問を超えていることを知っていますが、私はこの答えが本当に好きです。その答えはすっきりとしていて、非常に読みやすく、すぐに理解できるうえ、再利用も簡単です
Lski

についてparams:単一のラムダの内部からセレクターの配列を返し、各セレクターをマップするforeachか、Select()多分それほど乱雑に見えるわけではありません。
jpaugh、

@Steve Rukutsに感謝します。ソースメンバーを無視する拡張メソッドを探している人は、このpublic static IMappingExpression <TSource、TDestination> IgnoreSourceValidation <TSource、TDestination>(this IMappingExpression <TSource、TDestination> map、Expression <Func <TSource 、object >> selector){map.ForSourceMember(selector、config => config.DoNotValidate()); マップを返す; }
Jason Dias

79

あなたはこれを行うことができます:

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.Ignore());

オートマッパーにはForSourceMember拡張機能がありますか?
引き換え1 2012年

私は現在これを行っていますが、これらすべての無視を作成する必要がないのが理想的です...:/
Tom Stickel

マップを作成するときではなく、実際にマッピングを行うときに無視する方法があるかどうか知っていますか?
Sam I amはモニカを復活させる


3
質問で与えられたシナリオでは、これは受け入れられた答えであるはずです。現在受け入れられている回答は、宛先オブジェクトのプロパティのマッピングを無視します。この質問は、ソースオブジェクトのマッピングを無視することについて尋ねています。
Rob S.

28

これを自動的に実行しようとしている人のために、その拡張メソッドを使用して、宛先タイプに存在しないプロパティを無視できます。

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
        && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

次のように使用する:

Mapper.CreateMap<SourceType, DestinationType>().IgnoreAllNonExisting();

先端のためのCan Gencerに感謝します:)

ソース:http : //cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/



1
これは、IMapperを注入するときには機能しません。Mapper.GetAllTypeMapsは、AutoMapperの最新バージョンには存在しません。さらに、AutoMapper.Profileでマップを設定し、その後IMapperを挿入すると、「Mapper not initialize。Call Initialize with適切な構成。コンテナを通じてマッパーインスタンスを使用する場合など、静的なMapper.Mapメソッドへの呼び出しはありません。ProjectToまたはUseAsDataSource拡張メソッドを使用している場合は、適切なIConfigurationProviderインスタンスを渡してください。
Ristogod 2016

私はちょうど得る'Mapper' does not contain a definition for 'GetAllTypeMaps' [DSSTools]...
Bassie

2
@Bassie Use Mapper.Configuration.GetAllTypeMaps() source
Mike Bovenlander '20

28

これで(AutoMapper 2.0)IgnoreMap属性ができました。これは、やや重いIMHO である流暢な構文ではなく、使用する属性です。


35
ただし、ignore属性は、アプリケーションを通じて自動マッパーをリークします。
フィル

11
AutoMapperは、あちこちに漏れることを気にしないものの1つです。;)
Pawel Krakowiak

4
いつでも導出を検討できIgnoreMapAttributeます。
アラパゴ2014年

1
これは、多くのオブジェクト間で継承される基本プロパティを無視する良い方法です。すべてのマッピング設定で無視する必要がなくなります。
チェイスフローレル2018

23

ビューモデルをドメインモデルに再度マッピングする場合、宛先メンバーリストではなく、ソースメンバーリストを検証するほうがはるかにクリーンです。

Mapper.CreateMap<OrderModel, Orders>(MemberList.Source); 

Ignore()ドメインのクラスにプロパティを追加するたびに、マッピングの検証が失敗せず、別のが必要になりました。


7
これは私が探していたもので、非常に単純なDTOからドメインオブジェクトプロパティのサブセットのみを変更する場合にとても便利です。
Adam Tolley、2015

5
これが子供たちの答えです。初心者が混乱しないように、その公式にしてください
Piotr M

0

無視する必要があるプロパティでIgnoreAttributeを使用できます


2
その[IgnoreMap]からIgnoreMapAttribute
fiorebat

-5

こんにちはすべてくださいこれを使用してくださいこれは正常に動作しています...自動マッパーの場合はC#で複数の.ForMemberを 使用します

        if (promotionCode.Any())
        {
            Mapper.Reset();
            Mapper.CreateMap<PromotionCode, PromotionCodeEntity>().ForMember(d => d.serverTime, o => o.MapFrom(s => s.promotionCodeId == null ? "date" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", DateTime.UtcNow.AddHours(7.0))))
                .ForMember(d => d.day, p => p.MapFrom(s => s.code != "" ? LeftTime(Convert.ToInt32(s.quantity), Convert.ToString(s.expiryDate), Convert.ToString(DateTime.UtcNow.AddHours(7.0))) : "Day"))
                .ForMember(d => d.subCategoryname, o => o.MapFrom(s => s.subCategoryId == 0 ? "" : Convert.ToString(subCategory.Where(z => z.subCategoryId.Equals(s.subCategoryId)).FirstOrDefault().subCategoryName)))
                .ForMember(d => d.optionalCategoryName, o => o.MapFrom(s => s.optCategoryId == 0 ? "" : Convert.ToString(optionalCategory.Where(z => z.optCategoryId.Equals(s.optCategoryId)).FirstOrDefault().optCategoryName)))
                .ForMember(d => d.logoImg, o => o.MapFrom(s => s.vendorId == 0 ? "" : Convert.ToString(vendorImg.Where(z => z.vendorId.Equals(s.vendorId)).FirstOrDefault().logoImg)))
                .ForMember(d => d.expiryDate, o => o.MapFrom(s => s.expiryDate == null ? "" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", s.expiryDate))); 
            var userPromotionModel = Mapper.Map<List<PromotionCode>, List<PromotionCodeEntity>>(promotionCode);
            return userPromotionModel;
        }
        return null;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.