Thanks for taking your time!
I'm currently prototyping a smartphone webstore as a part of learning Entity Framework, I stumbled on a problem where new records in my database would add additional records in related tables. I managed to work around this problem by following this post Prevent Adding New Record on Related Table Entity in Entity Framework.
However, it seems quite tedious to add EntityState.Unchanged
for each and every entity whenever I want to add a record, so I'm starting to think I might have made an error.
Please take at the following code that is used for check out:
public ActionResult CheckOut()
{
// Save cart
Order order = new Order() { Payed = false, Canceled = false };
db.Orders.Add(order);
for (int i = 0; i < cartItems.Count; i++)
{
cartItems[i].Order = order;
cartItems[i].OrderId = order.OrderId;
db.CartItems.Add(cartItems[i]);
db.Entry(cartItems[i].Item).State = EntityState.Unchanged;
db.Entry(cartItems[i].Item.Memory).State = EntityState.Unchanged;
db.Entry(cartItems[i].Item.ScreenSize).State = EntityState.Unchanged;
db.Entry(cartItems[i].Item.OperatingSystem).State = EntityState.Unchanged;
}
db.SaveChanges();
cartItems.Clear();
return View();
}
The method takes whatever items the user has put into the cart and adds them into the database. If I don't set State
to EntityState.Unchanged
, the referenced entities will be added as new records into their corresponding tables.
For better understanding, here's the Item
entity and the CartItem
class:
public class Item
{
public int ItemId { get; set; }
public int MemoryId { get; set; }
public int OperatingSystemId { get; set; }
public int BrandId { get; set; }
public int ScreenSizeId { get; set; }
public string Name { get; set; }
public float Price { get; set; }
public Memory Memory { get; set; }
public OperatingSystem OperatingSystem { get; set; }
public ScreenSize ScreenSize { get; set; }
}
public class CartItem
{
public int CartItemId { get; set; }
public int OrderId { get; set; }
public int ItemId { get; set; }
public int Quantity { get; set; }
public Order Order { get; set; }
public Item Item{ get; set; }
}
What really grinds my gears is that if I combine the code that is used to add items into the cart and the checkout-method, I don't get this problem at all (notice the lack of state = EntityState.Unchanged
).
public ActionResult ProblemFreeCheckOut()
{
// Add Items to cart...
var item1= db.Items.Include(i => i.Memory).Include(i => i.OperatingSystem).Include(i => i.ScreenSize).Where(i => i.ItemId == 1);
var item2= db.Items.Include(i => i.Memory).Include(i => i.OperatingSystem).Include(i => i.ScreenSize).Where(i => i.ItemId== 2);
CartItems List<CartItems> = new List<CartItem>();
cartItems.Add(new CartItem { Quantity = 1, ItemId = item1.First().ItemId, Item = item1.First() });
cartItems.Add(new CartItem { Quantity = 1, ItemId= item2.First().ItemId, Item = item2.First() });
// Save cart
Order order = new Order() { Payed = false, Canceled = false };
db.Orders.Add(order);
for (int i = 0; i < cartItems.Count; i++)
{
cartItems[i].Order = order;
cartItems[i].OrderId = order.OrderId;
db.CartItems.Add(cartItems[i]);
}
db.SaveChanges();
cartItems.Clear();
return View();
}
To summarize and clarify what I'm trying to do: I want to be able to split the code above into two parts: one Add
method and one Checkout
method. The Add
method will add items from database into the a list of items that will later be utilized by the Checkout
method. I have got this working, by an excessive use of EntityState.Unchanged
- is this really needed?
Thanks a lot if you got this far in the post, I salute you!