EF4 не обновляет график «многие ко многим»; Или есть лучший способ справиться со многими ко многим в EF4? - PullRequest
0 голосов
/ 23 июня 2011

Моя текущая проблема выглядит как мутантная версия того, с чем я столкнулся несколько месяцев назад (см .: Проблемы с обновлением репозитория EF4 и MVC2 - невозможно обновить график «многие ко многим» ).Я могу создать новый граф Game-Platform, но я не могу редактировать сторону Platform существующего графика.Поэтому я не могу добавлять / удалять платформы из отношения.

Я использую AutoMapper для сопоставления входящих данных с сущностями.Затем я вручную присоединяю сущность Game к ObjectContext в моем хранилище и вручную устанавливаю его EntityState в зависимости от того, создаю ли я новый граф сущностей или обновляю существующий.Вот мои текущие настройки:

Отображение AutoMapper:

Mapper.CreateMap<AdminGameEditModel, Game>()
    .BeforeMap((s, d) =>
    {
        foreach (var platId in s.PlatformIDs)
        {
            Platform newPlat = _gameRepository.GetPlatform(platId);

            d.Platforms.Add(newPlat);
        }
    })
    .ForMember(dest => dest.BoxArtPath, opt => opt.Ignore())
    .ForMember(dest => dest.IndexImagePath, opt => opt.Ignore())
    .ForMember(dest => dest.Cons, opt => opt.MapFrom(src => String.Join("|", src.Cons)))
    .ForMember(dest => dest.Pros, opt => opt.MapFrom(src => String.Join("|", src.Pros)))
    .ForMember(dest => dest.LastModified, opt => opt.UseValue(DateTime.Now))
    .ForMember(dest => dest.Platforms, opt => opt.Ignore());

Метод GetPlatform моего репо:

public Platform GetPlatform(int id)
{
    Platform plat = _siteDB.Platforms.FirstOrDefault(pl => pl.PlatformID == id);
    _siteDB.Detach(plat);

    return plat;
}

И мой метод SaveGame:

public void SaveGame(Game game)
{
    _siteDB.Games.Attach(game);

    if (game.GameID > 0)
    {
        _siteDB.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Modified);
    }
    else
    {
        _siteDB.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Added);
    }

    _siteDB.SaveChanges();
}

Моя единственная мысль - мне нужно Remove() Платформы существующей игровой сущности.Я не уверен, как это сделать изящно с моими текущими настройками, поскольку у меня уже есть входящая свежая сущность Игры, отправляемая на SaveGame(), у которой есть новый список платформ.Я чувствую, что должен быть лучший, более изящный способ делать вещи.

Итак, есть идеи?Я пытаюсь не допустить, чтобы ссылки на мой пользовательский интерфейс (просмотр / редактирование моделей и т. П.) Проникли в слой моего домена, поэтому я не хочу, чтобы мое репо работало с моим AdminGameEditModel напрямую.

1 Ответ

1 голос
/ 23 июня 2011

нет способа сделать это изящно .Вам нужно сделать следующее:

  • Получить модель представления как есть (новое состояние)
  • Загрузить игру из базы данных вместе со всеми ее платформами (текущее сохраненное состояние)
  • Написать код, который пройдет через новое состояние и добавить или изменить платформы в текущем состоянии
  • Написать код, который пройдет через текущее состояние и удалить все платформы, не включенные в новое состояние
  • Сохранить изменения

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

Еще один более жестокий подход - загрузка текущего состояния, очистка коллекции платформ (все отношения удалены), а затем добавление всех платформ из нового состояния.

...