2017-01-24 9 views
0

У меня возникла проблема, я знаю, почему это проблема, но не знаю, как правильно ее исправить.Entity Framework: объект не может ссылаться на несколько экземпляров IEntityChangeTracker

Итак, мой контроллер отправляет Продукт в мой класс обслуживания вместе с 2 строками, определяющими категорию объекта.

Вот класс обслуживания.

public Product AddProduct(Product p, string cat, string subcat) 
{ 
    var category = _categoryService.GetCategoryByName(cat, subcat); 
    p.Categories.Add(category); 
    return _productRepository.CreateProduct(p); 
} 

Первая линия прибудет приведена категория поддержки существующей (CategroyService-> CategoryRepository-> DbContext), так что здесь я использую экземпляр моего контекста.

Затем я добавляю эту категорию в список категорий продукта. И, наконец, я даю репозиторию и сохраняю его в моей базе данных (корыто EF).

Тогда я получаю ошибку

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

Я думаю, это потому, что я первый просить категории, а затем попытаться добавить продукт. Затем трекер изменений должен отслеживать 2 контекста, и он запутывается. Дело в том, что я не понимаю, почему первый контекст из категории не удаляется, когда у меня есть моя категория.

Что мне делать?

EDIT:

_categoryService использует другой репозиторий, чем ProductRepository.

ответ

1

Проблема заключается в том, что вы используете больше экземпляров DbContext в одном запросе (единице работы), как вы уже упоминали.

При разработке веб-приложения наилучшим способом является работа с другим экземпляром DbContext для каждого веб-запроса, но exaccty 1 экземпляр для 1 запроса и вызов SaveChanges только 1 раз, когда вы внесли все необходимые изменения.

Это очень легко сделать, если вы используете инфраструктуру IoC, например Unity, и позволяете вашему DbContext вводить ваши репозитории.

В этом случае вы должны использовать следующие параметры (если вы используете Unity):

container.RegisterType<DbContext, YourDbContext>(new PerRequestLifetimeManager(), ...); 
+0

Спасибо! Я уже изменил некоторые обязанности, и действительно только один раз вызывал контекст и сохранял один раз – TanguyB