Automapper self referencing model projection

automapper c# entity-framework entity-framework-6

Question

I've got a problem handling self referencing model in my application using Automapper Projections. This is how my models look like:

public class Letter 
{
    public int? ParentId {get; set;}

    public Letter ParentLetter {get; set;

    public int Id {get; set;}

    public string Title {get; set;}

    public string Content {get; set;}

    public DateTime? ReceivedTime {get; set;}

    public DateTime? SendingTime {get; set;}

    public List<Destination> Destinations {get; set;}

    public List<Letter> Responses {get; set;}
}

public class LetterView 
{
    public int? ParentId {get; set;}

    public int Id {get; set;}

    public string Title {get; set;}

    public string Content {get; set;}

    public DateTime? ReceivedTime {get; set;}

    public DateTime? SendingTime {get; set;}

    public List<DestinationView> Destinations {get; set;}

    public List<LetterView> Responses {get; set;}
}


public class Destination 
{
    public int Id {get; set;}

    public string Name {get; set;}

    ..
}

public class DestinationView 
{
    public int Id {get; set;}

    public string Name {get; set;}
}

// The mapping:

CreateMap<Destination, DestinationView>
CreateMap<Letter, LetterView>

My problem is with mapping Letter to LetterView. The problem is somewhere with the Responses, I just can't figure out what should be changed.

Whenever running unit tests and asserting mapping configurations everything works, as well as mapping a letter with multiple responses to a view model. However, whenever I get a letter with it's resposnes from the database (Entity framework 6), the projection to LetterView throws a stackoverflow exception.

Can anyone please explain me why this happens only on projection? What should I change?

1
1
5/1/2016 9:50:41 AM

Popular Answer

A couple of options here, but usually the best choice is to set a max depth on the Responses. AutoMapper will try to spider the properties, and you've got a self-referencing DTO. First try this:

CreateMap<Letter, LetterView>()
    .ForMember(d => d.Responses, opt => opt.MaxDepth(3));

Another option is to pre-wire your DTOs with a specific depth. You'd create a LetterView, and a ChildLetterView. Your ChildLetterView would not have a "Responses" property, giving you exactly 2 levels of depth on your DTO side. You can make this as deep as you want, but be very explicit in the DTO types in where they are in the hierarchy with Parent/Child/Grandchild/Greatgrandchild type names.

1
4/29/2016 5:23:00 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow