gpt4 book ai didi

asp.net-mvc - 从对象上下文中分离实体

转载 作者:行者123 更新时间:2023-12-02 06:40:38 25 4
gpt4 key购买 nike

在我的模型中,我有两类类别和产品。它们之间存在多对多的关系。我在 Entity Framework 中使用代码优先方法。
我正在尝试制作一个编辑类别和产品之间映射的功能,但出现错误。

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.



我发现在 Entity Framework 中关闭连接后实体仍在跟踪。
所以我假设我必须从 ObjectContext 手动分离实体,但我的解决方案不起作用。这是我的 Controller 代码
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;
}
}

问题是我不知道哪些实体仍在跟踪。有什么情况可以检查吗?在 Debug模式或其他?

非常感谢您的解决方案。我不知道这个功能。我做了这个更改,错误消失了,但我还有其他问题。我在更新函数中将产品附加到上下文,但我的类别没有更新。所以我手动设置了所有类别的状态修改,当我在 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();
}
}

最佳答案

您收到此错误的原因是因为每次您有一个 using (EFDbContext context = new EFDbContext) ,实体专门附加到该上下文。如果您从一个上下文中读取实体,然后尝试将它们附加到另一个上下文以进行更新,您将收到 EF 无法在多个上下文中跟踪实体的错误。

当你从上下文中读取实体时试试这个:

context.Products.AsNoTracking().Single(m => m.ProductID == pro);

调用 AsNoTracking() ,您将确保返回的实体未附加到任何上下文。然后,您可以在更新/保存操作期间将其附加到另一个上下文。

关于asp.net-mvc - 从对象上下文中分离实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8711712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com