EF Core | Passing navigation properties in JSON body to API controller as POST request

EF Core | Passing navigation properties in JSON body to API controller as POST request

Here's the official docs on avoiding graph cycles in JSON: learn.microsoft.com/en-us/ef/core/change-tracking/… May 23 at 8:28
 
 

Attaching a serialized graph

EF Core works with graphs of entities connected via foreign keys and navigation properties, as described in Changing Foreign Keys and Navigations. If these graphs are created outside of EF Core using, for example, from a JSON file, then they can have multiple instances of the same entity. These duplicates need to be resolved into single instances before the graph can be tracked.

Graphs with no duplicates

Before going any further it is important to recognize that:

  • Serializers often have options for handling loops and duplicate instances in the graph.
  • The choice of object used as the graph root can often help reduce or remove duplicates.

If possible, use serialization options and choose roots that do not result in duplicates. For example, the following code uses Json.NET to serialize a list of blogs each with its associated posts:

 

 

Handling duplicates

The code in the previous example serialized each blog with its associated posts. If this is changed to serialize each post with its associated blog, then duplicates are introduced into the serialized JSON. For example:

Preserve references

Json.NET provides the PreserveReferencesHandling option to handle this. For example:

C#
var serialized = JsonConvert.SerializeObject(
    posts,
    new JsonSerializerSettings
    {
        PreserveReferencesHandling = PreserveReferencesHandling.All, Formatting = Formatting.Indented
    });

The resulting JSON now looks like this:

 

 

Notice that this JSON has replaced duplicates with references like "$ref": "5" that refer to the already existing instance in the graph. This graph can again be tracked using the simple calls to Update, as shown above.

The System.Text.Json support in the .NET base class libraries (BCL) has a similar option which produces the same result. For example:

var serialized = JsonSerializer.Serialize(
    posts, new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve, WriteIndented = true });

 

 

Resolve duplicates

If it is not possible to eliminate duplicates in the serialization process, then ChangeTracker.TrackGraph provides a way to handle this. TrackGraph works like Add, Attach and Update except that it generates a callback for every entity instance before tracking it. This callback can be used to either track the entity or ignore it. For example:

 

 

posted @ 2022-11-28 12:58  ChuckLu  阅读(4)  评论(0编辑  收藏  举报