0

I've configured the ASP.NET Core Web API using controller to use Sqlite as the database, and after the request of adding new item, the item is not being saved to the database.

The POST request endpoint is as follows:

[HttpPost("{cartId}/items", Name = "Adding item to Cart")]
public async Task<IActionResult> PostItemToCart(Guid cartId, [FromBody] CartAddItemDTO input)
{
    var cart = await _context.Carts.Include(c => c.Items).FirstOrDefaultAsync(c => c.CartId == cartId);

    if (cart == null)
    {
        return BadRequest("The cart Id does not exist");
    }

    var product = await _context.Products
                                .FirstOrDefaultAsync(p => p.Id == input.ProductId);     

    if (product == null)
    {
        return BadRequest("The product id does not exist");
    }

    cart.Items ??= new List<Product>();
    cart.Items.Add(product);

    await _context.SaveChangesAsync();

    return Created();
}

The ApplicationContextDB and models used in the code are under the Models folder.

I went through the C# debugger line by line and it looks like the Items in the cart is being added, just before the SaveChangesAsync(). However it doesn't look like the schema of cart is not being updated after the execution of the SaveChangesAsync(). I added the database debugger and the last SQL command being executed just before the save is the following:

Executed DbCommand (1ms) [Parameters=[@__input_ProductId_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT "p"."Id", "p"."CartId", "p"."Category", "p"."CurrentStock", "p"."Manufacturer", "p"."Name", "p"."Price"
FROM "Products" AS "p"
WHERE "p"."Id" = @__input_ProductId_0
LIMIT 1

What I was expecting is some sort INSERT INTO command but that doesn't seem to be happening. The issue seem to arise somewhere between cart.Items.Add(product); and await _context.SaveChagnesAsync();, and I can't seem to narrow down what the issue could be.

Another issue I can think of is the entity/configuration of the database and the way that I mapped one-to-many relationship between Cart (one) and Product (many). The list of products in Cart entity is called Items. In the ApplicationDbContext.cs, I have the following code on the method OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{
    // Seeding some data for Product table...

    // Entity Mapping Starts here
    modelBuilder.Entity<Product>()
                .HasOne(p => p.Cart)
                .WithMany(c => c.Items)
                .HasForeignKey(p => p.CartId);

    base.OnModelCreating(modelBuilder);
}
4
  • 1
    1) was not able to repro 2) you should have many-2-many relationship between carts and items, not one-2-many 3) Your GetCartItems is implemented incorrectly - it does not fetch Items (no Include or anything fetching related data, if you add include you will hit another problem - see this answer) Commented Jul 6, 2024 at 22:09
  • I believe the suggestion by @GuruStron is correct: I should have many-to-many relationship between the cart and products and have the GET endpoint retrieve the cart and Items from the joint table. Thanks! Commented Jul 7, 2024 at 0:33
  • Is the problem solved yet? Since in my test the currect code is correct and data saved as expected, and the sql error seems to be related to the lacking of include. However a get endpoint is unnecessay as include does the Eager loading for you. learn.microsoft.com/en-us/ef/core/querying/related-data/eager Commented Jul 8, 2024 at 9:55
  • Yes, it did require many-to-many relationship to work, and it turned out exactly I expected. I think next time I should have this issue in a docker container to be able to replicate the issue properly. Thank you for the reference @fengzhi-zhou Commented Jul 9, 2024 at 8:57

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.