Skip to content

Parents

Leonardo Porro edited this page Dec 10, 2024 · 10 revisions

Sometimes an associated entity also contains an association to the root entity which creates a circular dependency (i.e.: a graph that is not a tree).

In order to avoid stack overflows and errors when handling this case, the property pointing to the root entity must be marked as parent, by using the [Parent] attribute or .Parent() fluent configuration.

Annotated configuration

public class Invoice
{
   public int Id { get; set; }
   
   public string Name { get; set; }

   [Composition]
   public List<InvoiceRow> Rows{ get; set; }
}

public class InvoiceRow
{
   [Parent]
   public Invoice Invoice{ get; set; }

   public int Id { get; set; }

   public string Description { get; set; }

   public double Quantity { get; set; }

   public double PricePerItem { get; set; }
}

Fluent configuration

.UseMapping(profileOptions => {
    profileOptions .Default(mapperOptions => {
      mapperOptions.Type<InvoiceRow>().Member(i => i.Invoice).Parent();
    });
});

Parent mapping

When a member is marked as [Parent] instead of tring to get the value from the source object, the mapper uses MapContext object stack to look for a previous instance of the target object, already mapped.

A working integration test can be checked here. And here is the point in source code where it is implemented.