在我的模型中,我有两个类别和产品。他们之间存在着许多关系。我正在使用实体框架的代码优先方法。 我正在尝试创建一个编辑类别和产品之间映射的函数,但是我收到了一个错误。
实体对象不能被多个实例引用 IEntityChangeTracker。
我发现在实体框架中关闭连接后,实体仍在跟踪 所以我假设我必须从ObjectContext手动分离实体,但我的解决方案不起作用。这是我的控制器代码
public ActionResult Edit(int id)
{
Product product = db.Products.Find(id);
ViewData["categories"] = _categories.GetAllCategories();
ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Name", product.CompanyID);
return View(product);
}
[HttpPost]
public ActionResult Edit(FormCollection collection, Product product)
{
if (ModelState.IsValid)
{
_product.UpdateProduct(product);
_product.EditMappingProductCategories(collection, product.ProductID);
return RedirectToAction("ProductsList");
}
ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Name", product.CompanyID);
ViewData["categories"] = _categories.GetAllCategories();
return View(product);
}
我的服务层功能。我从表单收集新的类别,并根据结果我编辑产品。
public void EditMappingProductCategories(FormCollection collection , int pro)
{
using (EFDbContext context = new EFDbContext())
{
List<Category> list = new List<Category>();
Product product = context.Products.Single(m => m.ProductID == pro);
foreach (var item in collection.AllKeys)
{
if(collection[item].Contains("true"))
list.Add(context.Categories.Find(Convert.ToInt32(item)));
}
//Check if produkt contains marked category in formCollection
foreach (var item in list)
{
if (product.Categories.Contains(item))
{
product.Categories.Add(item);
context.Entry(item).State = EntityState.Detached;
}
}
context.SaveChanges();
//Check if product contains categories which are not marked in formCollection
foreach (var item in product.Categories)
{
if (list.Contains(item))
product.Categories.Remove(item);
}
context.SaveChanges();
UpdateProduct(product);
}
}
public void UpdateProduct(Product product)
{
using (EFDbContext context = new EFDbContext())
{
context.Entry(product).State = EntityState.Modified;
context.SaveChanges();
context.Entry(product).State = EntityState.Detached;
}
}
问题在于我不知道哪些实体仍在跟踪。有没有检查的情况?在调试模式还是其他?
非常感谢你的解决方案。我不知道这个功能。我做了这个改变,错误消失但我有其他问题。我在更新功能中将产品附加到上下文但我的类别没有更新。所以我手动修改所有类别的状态,当我在调试器中观看saveChanges()函数之前,我看到所有这些类别都被标记为已修改。 但是我的数据库中没有更新类别和产品之间的映射。 更新功能代码
public void UpdateProduct(Product product)
{
using (EFDbContext context = new EFDbContext())
{
context.Products.Attach(product);
if (product.Categories != null)
{
foreach (var item in product.Categories)
{
context.Entry(item).State = EntityState.Modified;
}
}
context.Entry(product).State = EntityState.Modified;
context.SaveChanges();
}
}
答案 0 :(得分:9)
您收到此错误的原因是每次有using (EFDbContext context = new EFDbContext)
时,实体都会专门附加到该上下文。如果您从一个上下文中读取实体,然后尝试将它们附加到另一个上下文以进行更新,您将收到EF无法在多个上下文中跟踪实体的错误。
在您从上下文中读取实体时尝试此操作:
context.Products.AsNoTracking().Single(m => m.ProductID == pro);
通过调用AsNoTracking()
,您将确保返回的权利不会附加到任何上下文。然后,您可以在更新/保存操作期间将其附加到另一个上下文。