EF Core reference loop when using Include and ThenInclude

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

Question

In my application, users can make requests for more information. I then need to be able to pull this information , but I also need to be able to see which bookings the user who made the request has already made.

I have set the following up with EF Core:

Models:

public class InfoRequest
{
    public int InfoRequestId { get; set; }
    public int UserId { get; set; }
    public User User { get; set }
}

public class User
{
    public int UserId { get; set; }
    public ICollection<Booking> { get; set; }
}

public class Booking
{
    public int BookingId { get; set; }
    public int UserId { get; set; }
    public User User { get; set }
}

Context:

modelBuilder.Entity<InfoRequest>(builder =>
{
    builder.ToTable("inforequests");
    builder.HasKey(x => x.InfoRequestId);
});

modelBuilder.Entity<User>(builder =>
{
    builder.ToTable("userdetails");
    builder.HasKey(x => x.UserId);

    builder
        .HasMany(x => x.Bookings)
        .WithOne(x => x.User)
        .HasForeignKey(x => x.UserId);
});

modelBuilder.Entity<Booking>(builder =>
{
    builder.ToTable("bookings");
    builder.HasKey(x => x.BookingId);
});

I am using the following code to pull the data I need:

public IQueryable<InfoRequest> GetAllInfoRequestsWithChildren()
    => this.Context.Set<InfoRequest>().AsNoTracking()
        .Include(x => x.User)
            .ThenInclude(x => x.Bookings);

Annoyingly, this is giving my the following self-referencing data structure which is obviously super slow:

InfoRequest
    -> User
        -> Booking
            -> User
                -> Booking
                    -> User
                        -> Booking
                            -> etc...

How can I prevent this from happening without pulling it all into memory with a ToList() and then removing the loop manually? I just want EF to not create a loop in the first place.

What I want is the following:

InfoRequest
    -> User
        -> Booking
1
1
1/29/2019 1:21:22 PM

Popular Answer

You cannot stop proxy creation while using Eager Loading in EF/EF Core. This is the default behavior of EF/EF core and no way to change this.

But may be (I didn't try out) you can stop the proxy creation for Lazy Loading in EF Core >=2.1 as EF Core documentation said.

But you can stop Self referencing loop due to the proxies while you converting the entity to JSON as follows:

public void ConfigureServices(IServiceCollection services)
{
    ...

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

    ...
}

For more details: Related data and serialization

2
1/29/2019 2:21:19 PM


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