Here are my models:
public class ShoppingCart
{
public CartHeader CartHeader { get; set; }
public IEnumerable<CartDetails> CartDetails { get; set; }
}
public class CartHeader
{
[Key]
public int CartHeaderId { get; set; }
public string UserId { get; set; }
public string? CouponCode { get; set; }
}
public class CartDetails
{
public int CartDetailsID { get; set; }
public int CartHeaderId { get; set; }
[ForeignKey("CartHeaderId")]
public virtual CartHeader CartHeader { get; set; }
public int ProductId { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; }
public int Count { get; set; }
}
Here is my code which populates the CartHeader
and CartDetails
tables:
var cartHeaderFromDb = await _dbContext.CartHeaders.AsNoTracking()
.FirstOrDefaultAsync(u => u.UserId == shoppingCart.CartHeader.UserId);
if (cartHeaderFromDb == null)
{
//create header and details
/// This creates CartHeader and CartDetails Records
_dbContext.CartDetails.Add(shoppingCart.CartDetails.FirstOrDefault());
await _dbContext.SaveChangesAsync();
}
else
{
//if header is not null
//check if details has same product
/// This block should only creates CartDetails and not create CartHeader, but it does
var cartDetailsFromDb = _dbContext.CartDetails.AsNoTracking().Where(u =>
u.CartHeaderId == cartHeaderFromDb.CartHeaderId).ToList();
if (!cartDetailsFromDb.Exists(c => c.ProductId == shoppingCart.CartDetails.First().ProductId))
{
//create details
shoppingCart.CartHeader = null;
shoppingCart.CartDetails.FirstOrDefault().CartHeaderId = cartHeaderFromDb.CartHeaderId;
_dbContext.CartDetails.Add(shoppingCart.CartDetails.FirstOrDefault());
await _dbContext.SaveChangesAsync();
}
else
{
//update the count / cart details
shoppingCart.CartHeader = null;
shoppingCart.CartDetails.FirstOrDefault().CartHeaderId = cartHeaderFromDb.CartHeaderId;
shoppingCart.CartDetails.FirstOrDefault().Count += cartDetailsFromDb.Count;
_dbContext.CartDetails.Update(shoppingCart.CartDetails.FirstOrDefault());
await _dbContext.SaveChangesAsync();
}
}
Here both if
and else
blocks create another CartHeader
record which I don't want. I want to use the same CartHeader ID, if there exists one. Tried AsNoTracking()
at various places and setting navigation properties to null
as well, no success! It always creates another CartHeader
record and the new CartDetails
gets that new CartHeader ID. I cannot figure out what I am missing here.
For anyone facing the same problem, I was able to resolve the issue using the following code.
_dbContext.CartDetails.Add(new CartDetails()
{
CartHeaderId = cartHeaderFromDb.CartHeaderId,
ProductId = shoppingCart.CartDetails.First().ProductId,
Count = shoppingCart.CartDetails.First().Count
}
await _dbContext.SaveChangesAsync();
With this code, no new CartHeader records are being created.
Comments are welcome to improve it. Thanks