❔ I apparently have an infinite loop, but I can't fix it to work

I've tried a lot of stuff, even a "NewtonJson" fix I saw, but it wouldn't solve the problem because whenever I would get all my movies, it would not include the MoviesParticipantsSeasons part With the Newtonjson, it would let me get MoviesParticipantsSeason with the includes though What am I doing wrong? Do I really need NewtonJson? Please help, been on this for days now :/
16 Replies
Jimmacle
Jimmacle2y ago
the problem is you have bidirectional navigation properties in your EF model which creates infinite cycles when you try to serialize it to JSON i would have separate models, one for your database and one for json serialization or for a quick and dirty solution, annotate the redundant properties so they're ignored by the json serializer
Marcoelho97
Marcoelho97OP2y ago
How would that work, exactly? I would use this model I already have for database creation And then another for _context.xyz?
Jimmacle
Jimmacle2y ago
you would define a new set of classes specifically to represent the data you want to serialize, then write a mapping function to convert your DB representation to that assuming you're returning this data as part of a web request you should really separate your database models and DTOs anyway for example, in one of my current projects i do things like this
public async Task<Result<ShippingOrderDetailsDto>> Handle(GetShippingOrderDetailsQuery request,
CancellationToken cancellationToken)
{
await using var db = await _db.CreateDbContextAsync(cancellationToken);
var order = await db.ShippingOrders.AsNoTracking()
.Include(o => o.RequestedBy)
.Where(o => o.Number == request.Number)
.Select(o => new ShippingOrderDetailsDto(
o.Number, o.RequestedBy.FullName, o.Description, o.Address, o.Method, o.CostCenter.Id + " " + o.CostCenter.Name, o.Packages,
o.CreatedOn, o.ShippedOn, o.TrackingNumber, o.CostUsd, o.Attn, o.ShipTo,
o.BillTo, o.Status, o.Project, o.Carrier, o.AccountNumber,
o.Packages.Sum(p => p.UnitValueUsd * p.Quantity)))
.FirstOrDefaultAsync(cancellationToken);
return order ?? Result<ShippingOrderDetailsDto>.Fail("Order not found.");
}
public async Task<Result<ShippingOrderDetailsDto>> Handle(GetShippingOrderDetailsQuery request,
CancellationToken cancellationToken)
{
await using var db = await _db.CreateDbContextAsync(cancellationToken);
var order = await db.ShippingOrders.AsNoTracking()
.Include(o => o.RequestedBy)
.Where(o => o.Number == request.Number)
.Select(o => new ShippingOrderDetailsDto(
o.Number, o.RequestedBy.FullName, o.Description, o.Address, o.Method, o.CostCenter.Id + " " + o.CostCenter.Name, o.Packages,
o.CreatedOn, o.ShippedOn, o.TrackingNumber, o.CostUsd, o.Attn, o.ShipTo,
o.BillTo, o.Status, o.Project, o.Carrier, o.AccountNumber,
o.Packages.Sum(p => p.UnitValueUsd * p.Quantity)))
.FirstOrDefaultAsync(cancellationToken);
return order ?? Result<ShippingOrderDetailsDto>.Fail("Order not found.");
}
ignore the ridiculous amount of properties
Marcoelho97
Marcoelho97OP2y ago
So Your model is ShippingOrders Your return is the ShippingOrderDetailsDto, in which you select every property you wanna return? So that you can "remove" the unwanted ones?
Jimmacle
Jimmacle2y ago
essentially correct
Marcoelho97
Marcoelho97OP2y ago
That is genius
Jimmacle
Jimmacle2y ago
i map the data in the database to an object that has the data the frontend needs it also means that if you ever need to change your database or API they aren't tightly coupled and you don't necessarily have to change them together
Jimmacle
Jimmacle2y ago
the DTO is a very simple object that's easy to serialize and only has the exact data needed by the endpoint
Marcoelho97
Marcoelho97OP2y ago
I'll give that a go :D Thank you so much!
Jimmacle
Jimmacle2y ago
(i don't actually serialize to JSON because this is a blazor server app, but the concepts apply either way)
Marcoelho97
Marcoelho97OP2y ago
But I still have a question, what about a create? How would I use a DTO and not the model? For example I create a movie Save I then create a relationship And when I go to save, it goes into loop too
Jimmacle
Jimmacle2y ago
you'd do the same thing but backwards your client sends JSON that you deserialize into a DTO, then translate that into your DB model
Marcoelho97
Marcoelho97OP2y ago
But the problem happens because of the DB Model, no? Because of that "Movie" and "MovieParticipantSeason" properties
Jimmacle
Jimmacle2y ago
the exception you got is related to reading/writing JSON, not your DB model EF core will handle navigation properties automatically
Marcoelho97
Marcoelho97OP2y ago
So, is it happening because I'm returning the object at its full? That makes sense 🤔 I will give this a try and give feedback :D Thank you so much! It worked! Thank you so much! ♥
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity. Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server