簡體   English   中英

Automapper-忽略基類的屬性

[英]Automapper - Ignore property on base class

我很難忽略從基類繼承的類的屬性。

Mapper.CreateMap<FormViewModelBase, EntityBase>()
.Include<FormViewModel, Entity>()
.ForMember(x => x.Id, o => o.Ignore());

Mapper.CreateMap<FormViewModel, Entity>();

這里唯一需要注意的是,基類的屬性是String,派生類的屬性是Int32。

無論如何,當我嘗試將FormViewModel的實例映射到Entity時,即使我已指定忽略它,但Entity類上基於String的Id屬性始終設置為FormViewModel的Int值。

我對FormViewModel和Entity使用不同類型的ID的原因是,我在Web應用程序中使用RavenDB,並且可以通過字符串或int Id加載對象。 在客戶端,最好使用Int Id,因為基於標准Raven字符串的ID在生成鏈接時不能很好地發揮作用。

誰能告訴我這里是什么問題?

那么您的基類看起來像這樣嗎?

public class FormViewModelBase
{
   public string Id { get; set; }
   // other stuff
}

您的派生類如下所示?

public class FormViewModel : FormViewModelBase
{
   public new int Id { get; set; }
   // other stuff
}

我以為是這樣。

如果是這種情況,則派生的Id隱藏了基本Id屬性。

無論如何,您是否傳遞了FormViewModel實際實例並從中創建Entity對象?

我看到這一行:

Mapper.CreateMap<FormViewModel, Entity>();

這對我說:“從發送給我的FormViewModel對象中創建一個新的Entity對象,並執行默認的常規操作來完成此任務。”

因此,當您調用類似的內容時:

var anEntity = AutoMapper.Mapper.Map<FormViewModel, Entity>(aFormViewModel);

將使用該Map,而不是用於基礎對象的Map。 因為它派生的FormViewModel

如果您做了類似的事情:

Mapper.CreateMap<FormViewModel, Entity>()
.ForMember(x => x.Id, o => o.Ignore());

我懷疑,如果要處理派生對象的映射,它會映射它,但是了解更多有關您要執行的操作可能會有所幫助。

您需要在子類而非父的映射中指定映射詳細信息(例如忽略某些屬性)。 例如:

Mapper.CreateMap<ParentA, ParentB>
      .Include<ChildA, ChildB>();

Mapper.CreateMap<ChildA, ChildB>
      .ForMember(dest => dest.SomeProperty, opt => opt.Ignore());

您的代碼無法正常工作的原因是您在父級映射上指定了Ignore()。

我知道這個問題已經一歲了,但是我還沒有找到可以回答此類問題的解決方案。 我遇到了相同的問題,經過一番挖掘后,我發現唯一的發現是這種行為沒有得到很好的記錄。 映射基類是可行的,但是由於某些原因卻不能忽略它們。

我使用了這種擴展方法,並為我解決了

public static IMappingExpression<TSource, TDestination>
        InheritMappingFromBaseType<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var sourceType = typeof(TSource);
        var desctinationType = typeof(TDestination);
        var sourceParentType = sourceType.BaseType;
        var destinationParentType = desctinationType.BaseType;

        expression
            .ForAllMembers(x => x.Condition(r => NotAlreadyMapped(sourceParentType, destinationParentType, r)));

        return expression;
    }

    private static bool NotAlreadyMapped(Type sourceType, Type desitnationType, ResolutionContext r)
    {
        return !r.IsSourceValueNull &&
               Mapper.FindTypeMapFor(sourceType, desitnationType).GetPropertyMaps().Where(
                   m => m.DestinationProperty.Name.Equals(r.MemberName)).Select(y => !y.IsMapped()).All(b => b);
    }

這就是它的使用方式(請注意,您將需要但要忽略基類映射中的ignore聲明)

CreateMap<DerivedClassSource, DerivedClassDestination>()
            .InheritMappingFromBaseType()

它所做的是映射未使用基類映射映射的任何屬性。 換句話說,它破壞了默認的映射優先級。

我在這里找到了源代碼並對其進行了修改,因為一些原始方法的代碼現在已在AutoMapper 2和3中實現。

在AutoMapper提出這個問題之后,未使用Include不添加Ignore的原因是因為無法忽略-映射仍可在基類中覆蓋。

當前可以實現此行為的唯一方法是用[IgnoreMap]屬性裝飾destination屬性,但這可能與其余配置不一致,因此,您需要確定是否值得!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM