I have come across an error “Self referencing loop detected for property…..” when working with EF Core.
Turns out, EF is trying to return data that inherently has a self-referencing loop. The Json serializer is trying to take your object graph and create a hierarchy.
For example, say we have an object called Order, an object called Product, and an object called OrderItem. The OrderItem will hold the information onto which Order it is associated with along with the Product that it is associated with.
We have a db graph like:
What is happening in the serializer is it is trying to create a hierarchy like:
If we want to return and see an Order and the OrderItems that are on that Order, the hierarchy tries to build out that the OrderItem has an Order object on it and the Order has a list of OrderItems on itself also.
To get around this issue, we can do one of 2 things.
- Add the “ReferenceLoopHandling = ReferenceLoopHandling.Ignore” to our JsonSerializerSettings.
- Use the [JsonIgnore] attribute on the offending Property. With the “Ignore” in place, we can call our Order information like this:
1
2
3
Context.Orders
.Include(o => o.Items)
.ToList();
And we will get a Json hierarch like this:
So, what if we wanted to have the Product information on each Order Item? A hierarchy like:
In order to get the Product, we just need to use the “ThenInclude” method to include a property from a sub-item. In this case, the Product (property in OrderItem) associated with the OrderItem (sub-item).
1
2
3
4
Context.Orders
.Include(o => o.OrderItem)
.ThenInclude(I => i.Product)
.ToList();