According to the documentation PreserveReferences should be set automatically whenever possible for AutoMapper.
Starting from 6.1.0 PreserveReferences is set automatically at config time whenever possible.
https://github.com/AutoMapper/AutoMapper/wiki/5.0-Upgrade-Guide
I have also tried setting MaxDepth to 1 but I still get a stack overflow exception with the following mapping. Can I get around this somehow or do I need to modify the view models?
cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
.MaxDepth(1)
.EqualityComparison((src, dst) => src.Id == dst.Id);
Code that causes the stack overflow exception:
var article = await iArticleRepository.GetAsync(id);
//The mapping below causes the exception
var mappedArticle = Mapper.Map<ArticleViewModel>(article);
Entities:
public class Article: IEntity<int>
{
[Key]
public int Id { get; set; }
...
public int SupplierId { get; set; }
public virtual Supplier Supplier { get; set; }
}
public class Supplier: IEntity<int>
{
[Key]
public int Id { get; set; }
...
public virtual ICollection<Contact> Contacts { get; set; }
}
public class Contact: IEntity<int>
{
[Key]
public int Id { get; set; }
...
public virtual ICollection<Supplier> Suppliers { get; set; }
}
View models:
public class ArticleViewModel
{
public int Id { get; set; }
...
public SupplierViewModel Supplier { get; set; }
}
public class SupplierViewModel
{
public int Id { get; set; }
...
public List<ContactViewModel> Contacts { get; set; }
}
public class ContactViewModel
{
public int Id { get; set; }
...
public List<SupplierViewModel> Suppliers { get; set; }
}
Well, it's unclear what does whenever possible mean. Since the documentation before that states
It turns out this tracking is very expensive, and you need to opt-in using PreserveReferences for circular maps to work
looks like your scenario fails into not possible category :)
Let not rely on that and use the explicit opt-in. The circular reference in this sample model is between Supplier
and Contact
, so you have to specify in one of the involved class mappings, for instance:
cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
.MaxDepth(1)
.EqualityComparison((src, dst) => src.Id == dst.Id);
cfg.CreateMap<SupplierViewModel, Supplier>(MemberList.Source)
.PreserveReferences()
.EqualityComparison((src, dst) => src.Id == dst.Id);