Home > Software design >  Include related entity in the controller
Include related entity in the controller

Time:07-31

When executing my GetPlans request, it doesn't include all the related classes

[ApiController]
[Route("api/[controller]")]
public class PlansController : Controller
{
    private readonly YnynContext _context;

    public PlansController(YnynContext context)
    {
        _context = context;
    }

    // GET: Plans
    [HttpGet(Name = "GetPlans")]
    public async Task<IActionResult> Index()
    {
          return _context.Plans != null ? 
                      Ok(await _context.Plans.ToListAsync()) :
                      Problem("Entity set 'YnynContext.Plans'  is null.");
    }
}

public class Room
{
    public int RoomId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public ICollection<Plan> Plans { get; set; }

    public CategoryEnum Category { get; set; }

}

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public ICollection<Plan> BuyerPlans { get; set; }

    public ICollection<Plan> SellerPlans { get; set; }

}

public class Plan
{
    public int PlanId { get; set; }
    public User Buyer { get; set; }
    public User Seller { get; set; }
    public Room Room { get; set; }

    public string Status { get; set; }

    public ICollection<Document> Documents { get; set; }

}

And my OnModelCreating looks like this:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Plan>().HasOne(a => a.Buyer).WithMany(b => b.BuyerPlans).OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<Plan>().HasOne(a => a.Seller).WithMany(b => b.SellerPlans).OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<Plan>().HasOne(a => a.Room).WithMany(b => b.Plans).OnDelete(DeleteBehavior.Restrict);
    }

I tried

Ok(await _context.Plans.Include(a => a.Buyer)
                       .Include(b => b.Seller)
                       .ToListAsync())

but it seems to create cycle error.

How do I include related classes?

Here is the actual response from the request:

[
  {
    "planId": 1,
    "buyer": null,
    "seller": null,
    "room": null,
    "status": "INPROGRESS",
    "documents": null
  }
]

CodePudding user response:

You need to .Include() the related data, for example

var person = await _context.People
    .Where(p => p.Id == id)
    .Include(p => p.Address)
    .FirstOrDefaultAsync();

Or better yet, .Select() the data into appropriate DTOs

var person = await _context.People
    .Where(p => p.Id == id)
    .Select(p => new PersonDto {
        Name = p.Name,
        Age = p.Age,
        // ...
        Address = new AddressDto {
            Street = p.Address.Street,
            City = p.Address.City,
            // ...
        }
    })
    .FirstOrDefaultAsync();
  • Related