6

メソッドからの動作を使用したい場合に AutoMapper マッピングを構成するUseDestinationValue方法ですが、宛先プロパティが NOT の場合のみですnull

そんな感じ:

Mapper.CreateMap<Item, ItemViewModel>()
    .ForMember(x => x.Details, _ => _.UseDestinationValue(dontUseWhenNullDestination: true))

編集

class ItemDetails {
    public string Info { get; set; }
    public string ImportantData { get; set; } // only in Domain, not in ViewModel
}

class Item {
    public ItemDetails Details { get; set; }
}

class ItemDetailsViewModel {
    public string Info { get; set; }
}

class ItemViewModel {
    public ItemDetailsViewModel Details { get; set; }
}

では使用例です。クラスがItemViewModelあり、それをクラスにマップしたいと考えていますItem

マッピング構成:

    Mapper.CreateMap<Item, ItemViewModel>()
        .ForMember(x => x.Details, _ => _.UseDestinationValue())
  1. 最初のケース - 宛先プロパティItem.Detailsプロパティが NOT NULL です。ここで、AutoMapperにプロパティのこの宛先インスタンスを使用さDetailsせたいと考えています。これは null ではないためです。

    ロジックは次のようになります。

    var item = new Item { 
        Details = new Details {
            Info = "Old text",
            ImportantData = "Data"
        }
    };
    
    var itemViewModel = new ItemViewModel { 
        Details = new DetailsViewModel {
            Info = "New text"
        }
    };       
    
    Mapper.Map(itemViewModel, item);
    

    が存在するため、AutoMapperはインスタンスUseDestinationValueを離れ、プロパティのみを設定します。item.Detailsitem.Details.Info

  2. 2 番目のケース - 宛先プロパティItem.Detailsプロパティが NULL です。ここで、AutoMapperでこの null インスタンスを使用せずに、新しいインスタンスを作成したいと考えています。問題は、このケースを考慮してマッピングを構成する方法です。

    ロジックは次のようになります。

    var item = new Item { 
        Details = null
    };
    
    var itemViewModel = new ItemViewModel { 
        Details = new DetailsViewModel {
            Info = "New text"
        }
    };
    
    Mapper.Map(itemViewModel, item);
    

    問題

    ここで問題があります。マッピング後、item.Detailsプロパティが null になるためです (この場合の使用法のためUseDestinationValue) null

理由

Hibernate は、データベースからエンティティーを取得した後、それをプロキシーに入れます。したがって、Details読み込まれたオブジェクトのプロパティは型ではありません:ですItemDetailsが、ItemDetailsNHibernateProxyこの既存のオブジェクトを後でデータベースに保存する場合は、この型を使用する必要があります。しかし、このプロパティがnullの場合、null の宛先値は使用できないため、Automapper は新しいインスタンスを作成する必要があります。

ありがとう、クリス

4

3 に答える 3

2

これと同じ問題がありましたが、EF. BeforeMap の使用に関する Cryss のコメントは、正しい方向を示してくれました。

次のようなコードになりました。

Configure() メソッドで:

Mapper.CreateMap<ItemViewModel, Item>()
           .AfterMap((s, d) => { MapDetailsAction(s, d); })
           .ForMember(dest => dest.Details, opt => opt.UseDestinationValue());

次に、アクション:

Action<ItemViewModel, Item> MapDetailsAction = (source, destination) =>
        {
            if (destination.Details == null)
            {
                destination.Details = new Details();
                destination.Details =
                    Mapper.Map<ItemViewModel, Item>(
                    source.Details, destination.Details);
            }
        };
于 2015-02-16T10:48:30.420 に答える
0

私はそのNullSubstituteオプションがあなたのために働くと思います。参照:http ://weblogs.asp.net/psteele/archive/2011/03/18/automapper-handling-null-members.aspx

編集

詳細のマッピングに少し条件付きロジックを追加する必要があるようです(そしてUseDestinationValueオプションをスキップします):

.ForMember(d => d.Details, 
    o => o.MapFrom(s => s.Details == null ? new ItemDetails() : Mapper.Map<ItemDetailsViewModel, ItemDetails>(s.Details))
于 2012-09-11T15:00:41.220 に答える
0

NHibernateエンティティを扱う際にも同じ問題があり、非常に簡単な解決策を見つけました。

ItemViewModel コンストラクターで Details プロパティを初期化する必要があります。このようにして、宛先値は null ではありません。もちろん、これはより複雑なケース (抽象クラスなど) では機能しません。

于 2012-11-14T08:26:59.603 に答える