Entity Framework Core disable recursive retrieval of information in .Include() function

.net-core asp.net asp.net-core entity-framework entity-framework-core

Question

The database has tables Machines, Wheels, Characteristics and Pilot. 1 record of the car includes 1 records about Pilot, 4 records of a wheel and several characteristics. In my Models class, it looks something like this:

public class Machines
{
    public int Id { get; set; }
    public string Description { get; set; }
    public string Color { get; set; }
    public int Weight { get; set; }
    public int Param { get; set; }

    public List<Characteristics> characteristics { get; set; }
    public List<Wheels> wheels { get; set; }
    public Pilot pilot { get; set; }
}
public class Characteristics
{
    public int Id { get; set; }
    public string Parameter { get; set; }
    public string Value { get; set; }
    public string Description { get; set; }

    public int MachineId { get; set; }
    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }

}
public class Wheels
{
    public int Id { get; set; }
    public int Radius { get; set; }
    public int Weight { get; set; }
    public int MachineId { get; set; }

    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }
}
public class Pilot
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; } 
    public int MachineId { get; set; }

    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }
}

When I try to download full information about a machine like this:

 var car  = context.Machines.Where(x => x.Id == 2)
                        .Include(m=> m.Wheels)
                        .Include(m=>m.Charateristics)
                        .Include(m=>m.Pilot)
                        .FirstOrDefault();

In response, I get a car that contains a pilot, an array of all the characteristics, and an array of wheels. But at the same time, the array of wheels contains again information about the car, which includes information about the wheels (but for the second time without a car).

It looks something like this:

{
"id": 2,
"Description": "",
"Color": "red",
"Weight": 2000,
"Pilot": {
    "id": 1,
    "Name": "John",
    "Description": ""
}, 
"Wheels": [
    {
        "id": 7,
        "Radius": 14,
        "Weight": 5,
        "MachineId": 2, 
        "machine": {
            "id": 2,
            "Description": "",
            "Color": "red",
            "Weight": 2000,
            "Pilot": {
                "id": 1,
                "Name": "John",
                "Description": ""
            }, 
            "Wheels": [
                {
                    "id": 7,
                    "Radius": 14,
                    "Weight": 5,
                    "MachineId": 2
                },
...

How do I get information without recursive data?

Also, the request takes a very long time (much longer than 4 separate requests). The Microsoft website says that you can disable the download if you remove the virtual keyword. I cleaned, but it did not help. Also in the context, I prescribed this.ChangeTracker.LazyLoadingEnabled = false; But this did not help either.

I also saw a lot where the use of the .Load() function is mentioned which can speed up the execution of the request, but I did not quite understand how to use it in my case.

UPDATE

Since everyone advises me to include Newtonsoft.Json.ReferenceLoopHandling.Ignore I will give my Startup and context files. In fact, I already have this enabled. Until I added this, I was not able to send a response at all, and after I added it, it began to come as I indicated (See JSON responce upper).

My context:

    public DbSet<Machines> machines{ get; set; }
    public DbSet<Characteristics> characteristics{ get; set; }
    public DbSet<Wheels> wheels{ get; set; }
    public DbSet<Pilot> pilot{ get; set; }

    public dbContext(DbContextOptions<dbContext> options) : base(options)
    {
        this.ChangeTracker.LazyLoadingEnabled = false;
    }

My Startup:

public void ConfigureServices(IServiceCollection services)
{
   ...

   services.AddDbContext<dbContext>(options => { 

        options.UseMySql(Configuration.GetConnectionString("DefaultConnection"), 
        builder =>
        {
            builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
        });
        }); 

        services.AddControllers().AddNewtonsoftJson(x =>
 x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

}
1
0
2/13/2020 11:00:19 AM

Popular Answer

For asp.net core 2.x,you could use the following code in your Startup.cs:

services.AddMvc().AddJsonOptions(options => 
         options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

For asp.net core 3.x,you need first install Microsoft.AspNetCore.Mvc.NewtonsoftJson then use the following code:

services.AddMvc().AddNewtonsoftJson(options=> 
         options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
2
2/13/2020 8:00:29 AM


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