Cześć mam pytanie chciałbym napisać mechanizm płacenia w sklepie ale gdy klikam zapłać
wyskakuje taki błąd System.InvalidOperationException: „An entity object cannot be referenced by multiple instances of IEntityChangeTracker.” błąd wyskakuje podczas db.SaveCHanges();
wiecie może jak to naprawić ?
Z góry dziękuje za pomoc :)
using Sklep.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web;
namespace Sklep.Infrastructure
{
public class OrderManager
{
private ISessionManager session;
private ApplicationDbContext db;
public OrderManager(ISessionManager session, ApplicationDbContext db)
{
this.session = session;
this.db = db;
}
public const string sessionKey = "BasketKey";
public List<OrderItems> GetBasket()
{
List<OrderItems> basket;
if(session.Get<List<OrderItems>>(sessionKey)==null)
{
basket = new List<OrderItems>();
}
else
{
basket = session.Get<List<OrderItems>>(sessionKey) as List<OrderItems>;
}
return basket;
}
public void AddToBasket(int productId)
{
var basket = GetBasket();
var basketItem = basket.Find(x => x.ProductId == productId);
if(basketItem != null)
{
basketItem.Quantity++;
}
else
{
var product = db.Products.Find(productId);
if(product!= null)
{
var newBasketItems = new OrderItems
{
Product = product,
ProductId = productId,
Quantity = 1,
Price = product.Price
};
basket.Add(newBasketItems);
}
}
session.Set<List<OrderItems>>(sessionKey, basket);
}
public int DeleteFromBasket(int productId)
{
var basket = GetBasket();
var basketItem = basket.Find(x => x.ProductId == productId);
if(basketItem != null)
{
basketItem.Quantity--;
return basketItem.Quantity;
}
else
{
basket.Remove(basketItem);
}
return 0;
}
public decimal GetTotalValue()
{
var basket = GetBasket();
return basket.Sum(x => (x.Product.Price * x.Quantity));
}
public int GetAmountBasketItems()
{
var basket = GetBasket();
return basket.Sum(x => x.Quantity);
}
public Order CreateOrder(Order newOrder, string UserId)
{
var basket = GetBasket();
var user = db.Users.SingleOrDefault(x => x.Id == UserId);
newOrder.DateOfAddition = DateTime.UtcNow;
newOrder.UserId = UserId;
db.Orders.Add(newOrder);
if (newOrder.OrderItems == null)
newOrder.OrderItems = new List<OrderItems>();
decimal basketValue = 0;
foreach (var item in basket)
{
var newOrderItems = new OrderItems()
{
ProductId = item.ProductId,
Product = item.Product,
Quantity = item.Quantity,
Price = item.Price,
};
basketValue += (item.Price * item.Quantity);
newOrder.OrderItems.Add(newOrderItems);
}
newOrder.TotalValue = basketValue;
db.SaveChanges();
return newOrder;
}
public void EmptyBasket()
{
session.Abandom();
}
}
}
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Sklep.Infrastructure;
using Sklep.Models;
using Sklep.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Sklep.Controllers
{
public class OrderController : Controller
{
private OrderManager orderManager;
private ISessionManager session { get; set; }
private ApplicationDbContext db;
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public OrderController()
{
session = new SessionManager();
db = new ApplicationDbContext();
orderManager = new OrderManager(session,db);
}
public OrderController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public ActionResult Index()
{
var orderItems = orderManager.GetBasket();
var totalValue = orderManager.GetTotalValue();
OrderViewModel vm = new OrderViewModel()
{
OrderItems = orderItems,
TotalValue = totalValue
};
ViewBag.Amount = orderItems.Count;
return View(vm);
}
public ActionResult AddToBasket(int id)
{
orderManager.AddToBasket(id);
TempData["message"] = "Pomyślnie dodano do koszyka";
return RedirectToAction("Index", "Home");
}
public int AmountItems()
{
var basketAmount = orderManager.GetAmountBasketItems();
return basketAmount;
}
public ActionResult DeleteFromBasket(int id)
{
var orderItems = orderManager.GetBasket();
var basketItem = orderItems.Find(x => x.ProductId == id);
if (basketItem.Quantity >= 2)
{
basketItem.Quantity--;
}
else
{
orderItems.Remove(basketItem);
}
var totalValue = orderManager.GetTotalValue();
OrderViewModel vm = new OrderViewModel()
{
OrderItems = orderItems,
TotalValue = totalValue
};
ViewBag.Amount = orderItems.Count;
return RedirectToAction("Index", vm);
}
[HttpGet]
public ActionResult Pay()
{
if(Request.IsAuthenticated)
{
var userId = User.Identity.GetUserId();
var user = UserManager.FindById(userId);
var order = new Order()
{
FirstName = user.FirstName,
SecondName = user.SecondName,
Adress = user.Adress,
City = user.City,
ZipCode = user.ZipCode,
Phone = user.PhoneNumber,
Email = user.Email
};
return View(order);
}
else
{
return RedirectToAction("Login", "Account", new { returnUrl = Url.Action("Pay", "Order") });
}
}
[HttpPost]
public ActionResult Pay(Order order)
{
if(ModelState.IsValid)
{
var userId = User.Identity.GetUserId();
var newOrder = orderManager.CreateOrder(order, userId);
var user = UserManager.FindById(userId);
TryUpdateModel(user);
UserManager.Update(user);
orderManager.EmptyBasket();
TempData["message"] = "Dziękujemy za złożenie zamówienia";
return RedirectToAction("Index", "Home");
}
else
{
return View(order);
}
}
}
}