Entity Framework 4.1: возможно ли сохранить одну таблицу из контекста данных, содержащего несколько таблиц? - PullRequest
0 голосов
/ 15 июля 2011

У меня проблема с курицей и яйцом, она тривиальна, поэтому я решил спросить, каков нормальный шаблон для сохранения агрегированного корня, где все первичные ключи являются полями идентичности.

У меня есть типичный контактный объект:

 Customer {
      HomeAddress {
      }
      WorkAddress {
      }
 }

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

Вот проблема:

  1. Мне нужно получить поле идентификатора Адреса для подключения внешних ключей, поэтому я сохраняю запись Адреса до сохранения записи Клиента, только если она уникальна, в противном случае я загружаю этот существующий Адрес.
  2. Если Адрес находится в том же DC, что и Клиент, то клиент слишком преждевременно сохраняет данные (не все записи установлены).
  3. Если Address находится в отдельном DC, он не подключается к записи клиента, имеющей собственный DC, поскольку у вас не может быть объекта, связанного с двумя DC (нельзя открыть в одном, а затем сохранить в другом).

Таким образом, я думаю, что мне потребуется отдельный репозиторий для каждого адреса, а затем отдельно загрузить адрес снова в другой DC, делая избыточные вызовы в базу данных для той же информации.

Есть ли способ частично сохранить записи в контексте данных / контейнере в Entity Framework 4.1? Например, чтобы сохранить адрес самостоятельно, находясь в том же DC?

1 Ответ

1 голос
/ 15 июля 2011

На ваш смелый вопрос, насколько я могу судить, ответ "Нет".Контекст является единицей работы, и SaveChanges фиксирует каждый новый, измененный или удаленный объект в базе данных за одну транзакцию.Вы не можете выборочно сказать: сохраняйте только тот или иной объект или сохраняйте только сущности в состоянии Added и не фиксируйте сущности в состоянии Modified или Deleted или что-то в этом роде.

В качестве обходного пути вы можете попробоватьчто:

using (var context1 = new MyContext())
{
    Address address = context1.Addresses.Where(predicate).FirstOrDefault();
    // if address != null it is attached now to context1
    if (address == null)
    {
        // ... otherwise create new address in another context and save
        using (var context2 = new MyContext())
        {
            address = new Address { Name = name, ... }
            context2.Addresses.Add(address);
            context2.SaveChanges();
        } // context2 destroyed now and address is not attached to it anymore
        // ... and attach to context1
        context1.Addresses.Attach(address);
    }

    customer.HomeAddress = address;

    // ...

    context1.SaveChanges();
}

Таким образом address никогда не привязывается к двум контекстам одновременно.Однако я не уверен, что это работает.

Редактировать

Я должен добавить (потому что мой код выглядит так странно), что "обычно" вы можете сделать все это вcontext1 один.Но я понял ваш пункт 2 таким образом, что в // ... (что я не понимаю) до SaveChanges что-то происходит, что не позволяет вам сохранить новый адрес и клиента одновременно.

...