Using .Include() in a database query creates an infinite loop of data

.net-core c# entity-framework-core linq


The problem: I'm using a LINQ to query against an Entity Framework context to a relational database. Following along with EFCore Relationships, I made a database with a few relationships, but when I sent the data to the server using ASP.NET, I got null values for these relationships.

With a little more digging, I found that I needed to use _context.Post.Include("Blog") to send the data since it uses lazy loading. However, by doing this, it created an "infinite loop" in the JsonResult.

The data that ends up getting returned appears to be cut in half and I get JSON parse errors when loading it because it's missing the second half of the JSON data.

Example return value

{"id": 0, "blogId": 1, "blog": {"postId":0

That's all it returns, as anything after that postId would be a reference back to the original post, which in turn has a reference to the blog. Is there any way that I can use LINQ to exclude the post object in the return, similar to how the blog was included in the first place?

12/16/2018 5:24:03 PM

Accepted Answer

Fixed! I took the model that came from the database with the relationship included, then used a foreach to null out the reverse reference.

var blog = await _context.Blog
    .Include(x => x.Posts)
    .SingleAsync(x => x.Id == id);

foreach (Post post in blog.Posts)
    post.Blog = null;
return Ok(blog);
12/13/2018 8:05:21 PM

Popular Answer

This is JSON serialization problem. Search how to solve "circulare references" problem in your JSON stream serializer documentation. Different stream serializers provide different solutions:

  1. configure max depth
  2. history based on references cache
  3. configure specific types serializers to do not use "navigation properties"

Other solution - do not use stream serializers - configure serializer function at place.

And another one - use DTO classes (where there are no circular references).

You can also try to detach your entities and set null to every navigation property you want to ignore but this is ugly and can't be recommended.

Related Questions


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