Как реализовать Aggregate Root репозиторий добавить дочернюю сущность с EF - PullRequest
0 голосов
/ 13 февраля 2012

Я разрабатываю приложение MVC.У меня есть модель предметной области, и я использую шаблон хранилища для доступа к данным и Entity Framework Code First.У меня также есть класс UnitOfWork, через который я вызываю операции с репозиторием.

Моя проблема в основном возникает, когда я пытаюсь воспользоваться преимуществами агрегатных корней и обрабатывать дочерние объекты через их родительский репозиторий.

ЭтоПроблема: у родительского класса «Поставщик» есть несколько договоров с отделами.В этом случае я решил сделать контракт дочерним по отношению к поставщику.

Чтобы добавить новый контракт, мне нужно добавить метод добавления контракта в моем репозитории Supplier, я попытался:

 public class SupplierRepository : GenericRepository<Supplier> 
        {

            public SupplierRepository(MyContext context) 
            : base(context)
            {
            }

            public void AddSupplierContract(SupplierContract contract)
            {
                 var supplier = context.Suppliers.Find(contract.SupplierId);
                 supplier.Contract.Add(contract);

            }

И я также попытался:

            public void AddSupplierContract(SupplierContract contract)
            {
                context.Entry(contract).State = EntityState.Added;
            }

         }

Когда я звоню

_unitOfWork.save();

Я получаю сообщение об ошибке:

Объект сущности не может бытьссылается на несколько экземпляров IEntityChangeTracker

UnitOfWork создает экземпляр моего DbContext (myDbContext) и моего SupplierRepository и вызывает myDbContext.Save ()

  1. Почему я получаю такое поведение
  2. Как мне реализовать Aggregate Root Repository (операции CRUD для дочерних объектов)

Насколько я понимаю, в репозитории должен быть метод, который берет контракт и добавляет его,и не делаю этого в контроллере моего приложения MVC, но мне кажется, что он не работает.

Я видел много информации об Aggregate Roots, но нет примеров того, как это реализовать.

чемks.

Решение:

Ну, я наконец-то понял это.

Так что это не было проблемой с хранилищем, но запросил новый SupplierContractхранилище для пользовательского объекта, который его создал (через метод расширения).Очевидно, этот контекст не располагал, и поэтому у меня было два текущих DbContexts, когда я его создал для сохранения сущности контракта.

Надеюсь, кто-то сэкономит время, прочитав это.

Хранилище Aggregate Root, которое я решил с помощьюпросто делаем так в репозитории Supplier:

    public void AddSupplierContract(SupplierContract contract)
    {
        db.SupplierContracts.Add(contract);
    }

и вызываем метод UnitOfWork.Save ().

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

Хотя технически вы, возможно, решили эту проблему, я надеюсь, что вы знаете, что в вашем дизайне есть что-то принципиально ошибочное (если вы не используете репозитории Фаулера): репозитории (типа DDD) работают только в агрегатах. Тот факт, что SupplierContract необходимо добавить в контекст, не имеет значения для вызывающего кода. Итак, зачем выставлять этот метод? Я бы также пересмотрел, чтобы репозиторий делегировал сохранение (почему еще есть UoW). Что касается агрегатов, я чувствую, что вы, похоже, рассматриваете их как структурные объекты, а не как поведенческие. Следовательно, вы, кажется, находитесь в мире боли, проходя через некоторые шаги, но не получая никакой ценности.

0 голосов
/ 13 февраля 2012

Чтобы избавиться от этой ошибки, вы должны использовать тот же экземпляр MyContext для создания всех репозиториев. Если вы используете некоторый инжектор зависимости, он должен позволить вам настроить один и тот же объект MyContext с помощью одного запроса. Например, для Ninject это будет

kernel.Bind<MyContext>().ToSelf().InRequestScope();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...