Отсоединение сущностей от контекста объекта - PullRequest
2 голосов
/ 03 января 2012

В моей модели у меня есть два класса категорий и продуктов. Между ними существует связь между многими. Я использую код первый подход с Entity Framework. Я пытаюсь создать функцию, которая редактирует сопоставление между категориями и продуктами, но я получаю сообщение об ошибке.

На объектный объект нельзя ссылаться несколькими экземплярами IEntityChangeTracker.

Я обнаружил, что сущности все еще отслеживаются после закрытия соединения в Entity Framework.
Поэтому я предполагаю, что мне приходится вручную отсоединять сущности от 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();
            }
        }

1 Ответ

9 голосов
/ 03 января 2012

Причина, по которой вы получаете эту ошибку, заключается в том, что каждый раз, когда у вас есть using (EFDbContext context = new EFDbContext), сущности привязываются именно к этому контексту. Если вы читаете сущности из одного контекста, а затем пытаетесь присоединить их к другому для обновления, вы получите ошибку, что EF не может отследить сущность в нескольких контекстах.

Попробуйте это, когда вы читаете сущности вне контекста:

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

Позвонив по номеру AsNoTracking(), вы убедитесь, что возвращенное право не привязано ни к какому контексту. Затем вы можете прикрепить его к другому контексту во время операции обновления / сохранения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...