AutoMapper:PreserveReferences 和 MaxDepth 有什么区别?

AutoMapper: What is the difference between PreserveReferences and MaxDepth?

我有点困惑。我无法找出 PreserveReferencesMaxDepth 之间的区别。

假设我们有以下 DTO 和模型。

public class PersonEntity
{
    public PersonEntity InnerPerson { get; set; }
}

public class PersonModel
{
    public PersonModel InnerPerson { get; set; }
}

如文档中所写:

Previously, AutoMapper could handle circular references by keeping track of what was mapped, and on every mapping, check a local hashtable of source/destination objects to see if the item was already mapped. It turns out this tracking is very expensive, and you need to opt-in using PreserveReferences for circular maps to work. Alternatively, you can configure MaxDepth.

我的映射:

cfg.CreateMap<PersonModel, PersonEntity>().MaxDepth(1);
cfg.CreateMap<PersonEntity, PersonModel>();

节目:

var personModel = new PersonModel();
personModel.InnerPerson = personModel;
var entity = Mapper.Map<PersonEntity>(personModel);

这就是我期望得到的:

这就是我实际得到的:

我可以同时使用它们(PreserveReferencesMaxDepth)来解决循环引用,但我看不出有什么区别。什么时候应该在 MaxDepth 方法中使用不同的深度?那么,有人可以提供吗?提前致谢。

MaxDepth 在运行时不考虑对象值。它只是在映射树的深度达到配置值后停止映射。

PreserveReferencesProjectTo 没有帮助,MaxDepth 有帮助。如果不知何故,使用 Map,您的映射树可能会溢出堆栈,但对象实例不会重复,那么 PreserveReferences 将无济于事,MaxDepth 会。

MaxDepth 是可预测的,它在硬编码值处停止,PreserveReferences 仅在复制对象实例时停止。

感谢@Lucian Bargaoanu 的回答。我只想添加一个 MaxDepth 的简单示例。

我最近更改了我的 DTO 和模型。

public class SelfEntity
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Number;
    public SelfEntity InnerSelfEntity { get; set; }
}

public class SelfModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Number;
    public SelfModel InnerSelfModel { get; set; }
}

映射:

cfg.CreateMap<SelfModel, SelfEntity>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(x => x.Id.ToString()))
.MaxDepth(3);

计划:

SelfModel firstSelfModel = new SelfModel();
SelfModel prev = firstSelfModel;

for (int i = 0; i < 100; i++)
{
   SelfModel newModel = new SelfModel
   {
      Id = Guid.NewGuid(),
      Name = "Test name" + i.ToString(),
      Number = i
   };

   prev.InnerFirstSelf = newModel;
   prev = newModel;
}

var entity = Mapper.Map<FirstSelfEntity>(firstSelfModel);

从第 3 层深度开始,我们将得到 null 对应 InnerSelfModel

PreserveReferences doesn't help with ProjectTo, MaxDepth does. If somehow, with Map, you have a mapping tree that might overflow the stack, but objects instances are not duplicated, then PreserveReferences won't help, MaxDepth will.