【问题标题】:ASP.NET MVC5,An entity object cannot be referenced by multiple instances of IEntityChangeTrackerASP.NET MVC5,一个实体对象不能被多个IEntityChangeTracker实例引用
【发布时间】:2015-05-21 09:53:15
【问题描述】:

当我尝试向数据库添加对象时,出现如下错误:

EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理 附加信息:一个实体对象不能被多个 IEntityChangeTracker 实例引用。

这是我的代码:

Order.cs

namespace OnlineMealOrdering.Models
{
    public class Order
    {
        [Key]
        public int Id { get; set; }
        public virtual User User { get; set; }
        public virtual Restaurant Restaurant { get; set; }
        public int TotalPrice { get; set; }
        public DateTime OrderTime { get; set; }
        public string Address { get; set; }
        public string UserTEL { get; set; }
        public string RestaurantTEL { get; set; }
        public string Memo { get; set; }
        public virtual ICollection<OrderDetail> OrderDetails { get; set; }
    }
}

OrderDetail.cs

namespace OnlineMealOrdering.Models
{
    public class OrderDetail
    {
        [Key]
        public int Id { get; set; }
        public virtual Order Order { get; set; }
        public Dish Dish { get; set; }
        public int Price { get; set; }
        public int Count { get; set; }
    }
}

购物车.cs

public class Cart
{
    public Dish Dish { get; set; }
    public int Count { get; set; }
}

控制器

public class OrderController : Controller
    {
        private OnlineMealOrderingContext db = new OnlineMealOrderingContext();

        List<Cart> Carts
        {
            get
            {
                if (Session["Carts"] == null)
                {
                    Session["Carts"] = new List<Cart>();
                }
                return (Session["Carts"] as List<Cart>);
            }
            set { Session["Carts"] = value; }
        }

 [HttpPost]
            public ActionResult Submit(string memo)
            {
                int user_id = (Session["Account"] as Account).Id;
                var user = (from p in db.Users
                            where p.Id == user_id
                            select p).FirstOrDefault();
                var restaurant = this.Carts.FirstOrDefault().Dish.Restaurant;
                int total_price = 0;
                foreach (var item in this.Carts)
                {
                    total_price += item.Dish.Price * item.Count;
                }
                Order order = new Order
                {
                    User = user,
                    Restaurant = restaurant,
                    TotalPrice = total_price,
                    OrderTime = DateTime.Now,
                    Address = user.Address,
                    UserTEL = user.TEL,
                    RestaurantTEL = restaurant.TEL,
                    Memo = memo,
                    OrderDetails = new List<OrderDetail>()
                };

                foreach (var item in this.Carts)
                {
                    order.OrderDetails.Add(new OrderDetail() { Dish = item.Dish, Price = item.Dish.Price, Count = item.Count });
                }

db.Orders.Add(order);

                db.SaveChanges();

                this.Carts.Clear();
                return RedirectToAction("Index", "Home");
            }

}

它发生在红色区域声明中。

【问题讨论】:

  • this.Carts 到底是什么?
  • @ErikFunkenbusch,我已经更新了问题。

标签: c# entity-framework asp.net-mvc-5


【解决方案1】:

很难说,因为您没有包含所有实体,但由于您的“Dish”对象来自存储在 Session 中的 List,我猜 Dish 也是从数据库中提取的。如果是这样,它可能属于 DbContext 的不同实例,因此当您尝试将其添加到您的 Orders 时,它会抱怨,因为 Dish 已经被您之前的实例跟踪。

顺便说一句,这就是为什么在会话中存储从 DbContext 获得的东西是一个坏主意的原因。而且它可以保留引用并导致内存泄漏。

【讨论】:

  • 呃,最方便的修改方法是什么。
  • @DrakFlameMaster - 我不知道你的应用程序的其余部分是如何工作的......所以我不可能说。您可能应该只从数据库中检索数据。
  • 我已经解决了问题,你是对的。这是会话的问题。
猜你喜欢
  • 1970-01-01
  • 2011-11-01
  • 2011-10-12
  • 1970-01-01
相关资源
最近更新 更多