I am working on creating an ASP.NET shopping cart with MVC.
My Store entitiy contains a DBSet of Basket. My Basket model, contains a list of BasketItems. The problem is, my "AddtoBasket" function, needs to search through the current list of BasketItems, and determine if an identical "basketitem" already exists, and if so, increase the qty. I am at a dead end on the shopping cart logic. How exactly would I search through my current list of "basketItems" ?
Store Context
public class StoreEntities : DbContext
{
public DbSet<Order> Order { get; set; }
public DbSet<OrderItems> OrderItems {get; set;}
public DbSet<Basket> Basket { get; set; }
public dbSet<BaskItem> BasketItems {get; set; }
}
Models
public class BasketItem
{
[Key]
public int BasketItemID { get; set; }
public string sellerID { get; set; }
public string sku { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
public class Basket
{
[Key]
public string BasketID { get; set; }
public virtual List<BasketItem> BasketItems { get; set; }
public System.DateTime DateCreated { get; set; }
}
Shopping Cart Logic
public void AddtoBasket(BasketItem basketItem)
{
//Search Current Basket for basketItem
//
//If item doesnt exists, add it
if (basketItem == null){
basketItem = new BasketItem
{
sku = "",
sellerID = "",
Quantity = 1,
Price = 100
};
storeDB.BasketItems.Add(basketItem);
storeDB.SaveChanges();
}
else
{
basketItem.Quantity = +basketItem.Quantity;
storeDB.SaveChanges();
}
}
#endregion
Well, I guess that the basket item you are receiving does not have BasketItemID (as it is the key and you are probably getting its default value). The key question here is how do you define "already exists". For the sake of the argument, I will assume that the sellerId (please, follow PascalCase for your properties, this is generally the accepted convention for property names) and sku (whatever that is) need to be equal. So the obvious way to do that in the current case is this:
var basketItem = <yourCurrentBasket>.BasketItems.
Where(bi => bi.sellerId == basketItem.sellerID && bi.sku == basketItem.sku);
Now, you will note that I have not specified how you will retrieve your current basket. That is because this is an architectural decision and, at least from what you have provided, I do not see you implementing it. The best way to do lookup is for you to be able to look up the basket by user (that means adding an UserId
(whatever your unique user identifier is) to your Basket
class. Whether you implement the functionality of the user having 2 or more active baskets at once depends on your use case and requirements - and you should handle that appropriately.
According to me (and a lot of other people) the best place to store user id/any other unique identifier is in the Session
(depending on your authentication mode, you may have other options:
see this topic for more details
)
Then, the lookup becomes as simple as this (in case of only 1 active basket per user - handling the multi-basket case is not significantly more complicated):
public class Basket
{
[Key]
public string BasketID { get; set; }
public virtual List<BasketItem> BasketItems { get; set; }
public System.DateTime DateCreated { get; set; }
public Guid UserId { get; set; }
}
...
var basketItem = storeDb.Basket.Where(basket => basket.UserId == currentUserId)
.Include(basket => basket.BasketItems ).Where(bi => bi.sellerId == basketItem.sellerID && bi.sku == basketItem.sku);