EF 4.1 Code First: запуск обновления «многие ко многим» - PullRequest
1 голос
/ 06 июля 2011

У меня есть объект BusinessUnit, который имеет отношение "многие ко многим" с объектом "Контакт". Мы используем конфигурацию Fluent в соответствии с примером ниже:

public BusinessUnitConfiguration()
{
    HasMany(c => c.Contacts)
        .WithMany()
        .Map(m =>
            {
                m.ToTable("BusinessUnitContact");
                m.MapLeftKey("BusinessUnitId");
                m.MapRightKey("ContactId");
            });

    ToTable("BusinessUnit");
}

public ContactConfiguration()
{
    ToTable("Contact");
}   

Сущность Contact не знает, с какими родителями она может быть связана. Мы используем Silverlight + WCF, поэтому отложенная загрузка и создание прокси отключены.

Мы создаем или модифицируем граф объектов на клиенте, состоящем из экземпляра BusinessUnit и нулевого или более экземпляров Contact, затем отправляем в службу WCF для сохранения, где создается новый контекст, и мы добавляем / присоединяем / удаляем по необходимости, прежде чем сохранение изменений.

Проблема в том, что если я добавляю новый контакт в коллекцию контактов в существующем подразделении, EF не вставляет запись о соединении - он знает, как добавить новый контакт, потому что я его добавил, но не BusinessUnitContact строка, отображающая бизнес-единицу в контакт.

Свойство Contacts в BusinessUnit является ObservableCollection . Он работает при добавлении родительской бизнес-единицы, но не при подключении.

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

1 Ответ

0 голосов
/ 06 июля 2011

Я нашел проблему. Код, который прикреплял родительский объект к контексту EF, на самом деле не подключал его напрямую - он загружал исходный объект, а затем объединял свойства из присоединяемого объекта:

// attach entity
var existing = GetQuery<TEntity>().FirstOrDefault(e => e.Id == entity.Id);
if (existing == null)
{
   throw new InvalidOperationException("Cannot attach an entity that does not exist in the database.");
}

switch (entity.State)
{
    case ObjectState.Modified:
        GetEntry(existing).CurrentValues.SetValues(entity);
        break;

    case ObjectState.Deleted:
        GetEntry(existing).State = EntityState.Deleted;
        break;
}

Это, похоже, не работает для свойств навигации, поэтому я изменил код следующим образом:

var set = GetSet<TEntity>();
set.Attach(entity);

// map object state to entity state
switch (entity.State)
{
    case ObjectState.Modified:
        GetEntry(entity).State = EntityState.Modified;
        break;

    case ObjectState.Deleted:
        GetEntry(entity).State = EntityState.Deleted;
        break;
}

Все, что нужно было изменить, - это убедиться, что присоединяемый объект совпадает с входящим объектом - объект BusinessUnit также не нужно изменять.

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