How to avoid cyclic relationships in EF Core 8

46 Views Asked by At

I have these tables:

enter image description here

On the other hand, I have a Web API that returns an entity Trabajador whose primary key is specified.

The problem I have is that when loading TurnoPorTrabajador entities, a JSON error occurs since TurnoPorTrabajador includes Trabajador which, in turn, also contains TurnoPorTrabajador, and so on, ad infinitum.

I do this in EF Core 8; this was my last attempt:

public async Task<Trabajador?> GetByIdAsync(int id)
{
    var turnos = await db.TurnoPorTrabajador
            .Where(tt => tt.TurnoPorTrabajadorElminadoEn == null && tt.TrabajadorId == id)
            .ToListAsync();
    var trabajador = await db.Trabajador
        .Include(t => t.Ubicacion.Where(u => u.UbicacionEliminadoEn == null))
        .Include(t => t.Area.Where(a => a.AreaEliminadoEn == null))
        .FiltraEmpresaCliente(this, t => t.ExtEmpresaId)
        .FirstOrDefaultAsync(t => t.TrabajadorEliminadoEn == null && t.TrabajadorId == id);

    if (trabajador != null)
        trabajador.TurnoPorTrabajador = turnos;

    return trabajador;
}

At first, I had an Include in the main query, but, lastly, I tried to do separate queries but the same problem happens.

When I retrieve turnos, it does not return Trabajador relationship, but when executing that if, Trabajador entity is returned also.

The JSON error is this for you to better understand the problem:

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.Data.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TurnoPorTrabajador.Trabajador.TrabajadorId. at System.Text.Json.ThrowHelper.ThrowJsonException_SerializerCycleDetected(Int32 maxDepth)

$.Data is of Trabajador entity type.

Since this is returned by the Web API, I cannot control how the object is json serialized.

How can I accomplish this?

EDIT:

by using:

.AddJsonOptions(options =>
        options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve)

Any JSON object cannot be converted to object. If I add those options, some weird properties are added to the JSON string, making impossible to convert to a C# object;

ValueKind = Object : "{"$id":"2","$values":[{"$id":"3","clienteId":15,"ciudadId":66,"tipoDocumentoId":1, ......

Notice the properties preceeded by $.

0

There are 0 best solutions below