Search code examples
c#linq.net-coreasp.net-core-webapief-core-2.0

EF Core does not include all the child items


I am using EF Core and .NET Core 2.0.

I have this entity hierarchy:

  • Order

    • OrderItem

      • Product

My LINQ query in the service works, but only returns one OrderItem and I have 5. It also returns well the product for that OrderItem. So what I want is, modify this query to include actually all the OrderItems I have for a particular order Id, not only the first item. I was expecting the include to do that job for me.

public class Order
{
    public int Id { get; set; }
    public DateTime OrderDate { get; set; }
    public decimal TotalPrice { get; set; }
    public List<OrderItem> OrderItems { get; set; }

    public decimal CalculateTotal()
    {
        return OrderItems.Sum(item => item.GetPrice());
    }
}

public class OrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
    public Product Product { get; set; }
    public Order Order{ get; set; }

    public decimal GetPrice()
    {
        return Product.Price * Quantity;
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
}

and this is the service with the query:

public class OrderRepository: IOrderRepository
{
    private readonly BasketDbContext _basketDbContext;
    public OrderRepository(BasketDbContext basketDbContext)
    {
        _basketDbContext = basketDbContext;
    }

    public IEnumerable<Order> GetAllOrders()
    {
        return _basketDbContext.Orders
            .Include(x => x.OrderItems)
            .ThenInclude(y => y.Product).ToList();
    }
}

And this is the JSON I got from the method GetAllOrders:

[  
    {  
      "id":1,
      "orderDate":"2019-02-02T11:24:36.103",
      "totalPrice":0.0000,
      "orderItems":[  
         {  
            "id":1,
            "orderId":1,
            "productId":1,
            "quantity":1,
            "product":{  
               "id":1,
               "name":"Samsung Galaxy S8 64GB",
               "description":"5.8-Inch, Dual pixel 12MP camera",
               "price":390.0000
            }

As you can see, the JSON is also not well formatted, it does not close the initial [{.

What I am doing wrong? Thanks for the help


Solution

  • This looks like in the final step of the serialization your serializer is not able to proceed hence just exits and ASP.NET Core sends the unfinished response to the client. Maybe this happens because of your backreference from OrderItem to Order. Assuming you are using Newtonsoft's Json.NET, try setting JsonSerializerSettings to ReferenceLoopHandling = ReferenceLoopHandling.Ignore in your Startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMvc()
        .AddJsonOptions(
            o => o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        );
    }
    

    Another option would be to simply exclude the Order in OrderItem from serialization, e.g. via the [JsonIgnore] attribute, however, this of course means that it will never showup in any of your responses.