添加订单时触发IEntityChangeTracker多实例引用错误求助
解决EntityFramework多上下文跟踪错误:An entity object cannot be referenced by multiple instances of
IEntityChangeTracker 问题场景
执行context.Orders.Add(order);时触发错误:
An entity object cannot be referenced by multiple instances of
IEntityChangeTracker
尝试向数据库添加订单,怀疑问题出在用户/客户的获取方式上,相关代码如下:
// get user string userId = User.Identity.GetUserId(); var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); var user = userManager.FindById(userId); Models.Customer customer = user as Models.Customer; // create order Order order = new Order(); order.CustomerId = userId; order.Customer = customer; order.OrderStatus = OrderStatus.New; order.OrderDate = DateTime.Now; order.OrderLines = (List<OrderLine>)Session["basket"]; order.IsPaid = false; // get orderLines from session basket List<OrderLine> basket = (List<OrderLine>)Session["basket"]; // calculate order total order.OrderTotal = (from data in basket select data.Product.Price * data.Quantity).Sum(); // save to database context.Orders.Add(order); context.SaveChanges();
错误原因
- 通过
ApplicationUserManager获取的customer对象,被UserManager对应的DbContext实例跟踪 - 保存订单时使用的
context是另一个独立的DbContext实例 - 当把
customer赋值给order.Customer时,EF检测到同一个实体被两个不同上下文跟踪,因此抛出错误
修复方案
方案1:仅关联外键,不赋值实体对象
既然已经设置了order.CustomerId = userId;,EF会自动通过外键关联对应的Customer,无需再赋值实体对象。修改代码如下:
// create order Order order = new Order(); order.CustomerId = userId; // 移除该行:order.Customer = customer; order.OrderStatus = OrderStatus.New; order.OrderDate = DateTime.Now; order.OrderLines = (List<OrderLine>)Session["basket"]; order.IsPaid = false;
方案2:让Customer归当前订单上下文跟踪
如果需要在订单中使用Customer实体的其他属性,用当前订单上下文重新获取Customer,替换UserManager获取的实例:
// 替换原获取customer的代码 string userId = User.Identity.GetUserId(); // 用当前订单上下文查询customer var customer = context.Customers.Find(userId); // create order Order order = new Order(); order.CustomerId = userId; order.Customer = customer; // 其余代码保持不变
额外注意点
Session中的OrderLine及关联的Product如果来自其他上下文实例,也可能触发相同错误。建议:
- 仅将
ProductId和Quantity存入Session,而非整个实体对象 - 添加订单前,将Session中的实体附加到当前上下文,或重新查询一次Product
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

