使用 Automapper 深度克隆对象,无法排除列表 <abstractBaseClass> 属性 中对象的 ID 属性

Deep cloning an object with Automapper, can't exclude Id property on objects in a List<abstractBaseClass> property

我有以下 classes:

public abstract class Question : IQuestion
{
  [Key]
  public int Id { get; set; }

  // Some other base properties here
}

public class TextQuestion : Question
{
  // Some class-specific properties here
}

还有一个 class 这样的:

public class SomeCompositeClass
{
  [Key]
  public int Id { get; set; }

  // Some properties go here ...

  public virtual List<Question> Questions { get; set; }
}

我想创建 SomeCompositeClass 的深层克隆,使用 Automapper(请不要建议 ICloneable),但没有所有 ID,因为我会将其插入数据库,我使用 EntityFramework、存储库模式访问。

当然,我创建一个映射:

Mapper.CreateMap<SomeCompositeClass, SomeCompositeClass>().ForMember(rec => rec.Id, opt => opt.Ignore())

这对 SomeCompositeClass 非常有用。

但是我对问题 属性 做同样的事情时遇到了问题!问题出在列表中的基数class是abstract,不是因为列表本身是virtual,我已经排除了。

如果我创建 Mapper.CreateMap<Question, Question>()Mapper.CreateMap<IQuestion, IQuestion>() 映射,代码会在运行时抛出异常,抱怨它无法创建抽象 (Question) 对象的实例。

我试过 Mapper.CreateMap<List<Question>, List<Question>>(),但这只会在运行时给我一个空的 Questions 列表。

我已经尝试创建特定问题的映射(TextQuestionTextQuestion),但它们没有启动,因为 Questions 属性 中的对象包裹在 EF 的 DynamicProxy classes.

在 Mapper.Map(...) 期间,我该怎么做才能将 Id 从我的抽象基础 Question class 的继承者中排除?

我是这样解决的:

首先,我更新到Automapper 4.1.1。那么:

        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<Question, Question>()
                .Include<TextBoxQuestion, TextBoxQuestion>()
                    // Supposedly inheritance mapping?
                    .ForMember(rec => rec.Id, opt => opt.Ignore());

            cfg.CreateMap<TextBoxQuestion, TextBoxQuestion>()
                // But either I don't understand inheritance mapping or it doesn't work, soI have to do that too
                .ForMember(rec => rec.Id, opt => opt.Ignore());

            cfg.CreateMap<SomeCompositeClass, SomeCompositeClass>()
                .ForMember(rec => rec.Id, opt => opt.Ignore())
        }

        ...
        Mapper.Map(source, destination);

而且有效...

所以我认为我最缺少的是 .Include 部分,它告诉 Automapper 寻找最派生的 class.