1

我很难忽略从基类继承的类的属性。

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 在生成链接时效果不佳。

谁能告诉我这里有什么问题?

4

4 回答 4

1

所以你的基类看起来像这样?

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

你的派生类看起来像这样?

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

我假设是这样的。

如果是这种情况,那么派生的 Id 将隐藏基本 Id 属性。

无论如何,你是在传递 a 的实际实例并从中FormViewModel制作对象吗?Entity

我看到这一行:

Mapper.CreateMap<FormViewModel, Entity>();

这对我说:“Entity从我发送给您的对象中为我创建一个新对象,FormViewModel并执行默认的常规操作来完成此操作。”

因此,当您调用以下内容时:

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

它将使用该地图,而不是用于基础对象的地图。因为它派生的FormViewModel

如果你做了类似的事情:

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

为了处理派生对象的映射,我怀疑它会像您想要的那样映射它,但更多地了解您正在尝试做的事情可能会有所帮助。

于 2013-05-10T16:11:20.803 回答
0

我知道这个问题已经有一年了,但我还没有在 SO 中找到可以回答这类问题的解决方案。我有同样的问题,经过一番挖掘,我发现唯一的事情是这种行为没有很好的记录。并且映射基类有效,但由于某种原因忽略它们不起作用。

我使用了这种扩展方法,它对我有用

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);
    }

这就是它的使用方式(请注意,您将需要忽略基类映射中的声明)

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

它所做的是映射任何未使用基类映射映射的属性。换句话说,它破坏了默认的映射优先级。

我在这里找到了源代码并对其进行了一些修改,因为一些原始方法的代码现在在 AutoMapper 2 和 3 中实现。

于 2014-07-06T20:19:32.027 回答
0

您需要在子类而不是父类的映射中指定映射详细信息(例如忽略某些属性)。例如:

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

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

您的代码不起作用的原因是您在父映射上指定了 Ignore() 。

于 2013-11-08T03:47:36.227 回答
0

将此问题作为 AutoMapper 提出后,未使用 Include 添加 Ignore 的原因是因为无法取消忽略 - 映射仍然可以在基类中被覆盖。

当前实现此行为的唯一方法是使用属性装饰目标[IgnoreMap]属性,但这可能与您的其余配置不一致,因此您需要决定是否值得!

于 2015-10-23T15:24:44.913 回答