Это довольно сложно объяснить, поэтому, пожалуйста, потерпите меня.
У меня есть проект ASP.NET MVC 2 , который медленно убивает меня , в котором я пытаюсь взять данные формы и преобразовать их в сущности для создания или обновления, в зависимости от контекста ситуации , Наиболее значимые части (псевдокод):
Entity Game
Scalar properties
EntityCollection<Platform> Platforms
И основной рабочий процесс:
Данные формы -> модель, связанная с DTO -> сопоставление DTO с сущностью EF4 с помощью AutoMapper.
Все это работает хорошо, за одним исключением - мне нужно создать или обновить EntityCollection Platforms объекта Game с необработанными целочисленными индексными данными, содержащимися в DTO. Итак, вот что я пытался, который не работает:
public AdminController(IArticleRepository articleRepository, IGameRepository gameRepository, INewsRepository newsRepository)
{
_articleRepository = articleRepository;
_gameRepository = gameRepository;
_newsRepository = newsRepository;
Mapper.CreateMap<AdminGameEditModel, Game>()
.BeforeMap((s, d) =>
{
if (d.Platforms.Count > 0)
{
Platform[] existing = d.Platforms.ToArray();
foreach (var plat in existing)
{
d.Platforms.Remove(plat);
}
}
foreach (var platId in s.PlatformIDs)
{
var newPlat = _gameRepository.GetPlatform(platId);
d.Platforms.Add(newPlat); // <-- where it chokes
}
})
.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());
}
Если быть точным, я получаю исключение в строке, которую я выделил выше, которая говорит:
Невозможно определить отношения между двумя объектами, поскольку они связаны с различными объектами ObjectContext.
Некоторые исследования говорят мне, что этого следовало ожидать, поскольку мой новый объект Game не имеет ObjectContext, с которым он связан, и нулевой контекст считается отдельным контекстом. См. это краткое объяснение от Джули Лерман для получения дополнительной информации.
Хорошо, так как я бесстрашный человек, я подумал, что просто смогу зарегистрировать свою игру с ObjectContext, и все будет исправлено. Итак, я попробовал:
Game game = new Game();
_gameRepository.RegisterGame(game);
Где RegisterGame просто:
public void RegisterGame(Game game)
{
_siteDB.Games.AddObject(game);
}
К сожалению, это не сработало. В ту же точку выдается то же исключение.
Итак, похоже, мне придется добавить EntityKey каждой платформы в мою коллекцию EntityCollection. Единственная проблема, я не уверен, как это сделать.
Итак, есть идеи?
РЕДАКТИРОВАТЬ: прогресс в некотором роде. Я попытался добавить только EntityKeys для объектов Platform, например:
Mapper.CreateMap<AdminGameEditModel, Game>()
.BeforeMap((s, d) =>
{
if (d.Platforms.Count > 0)
{
Platform[] existing = d.Platforms.ToArray();
foreach (var plat in existing)
{
d.Platforms.Remove(plat);
}
}
foreach (var platId in s.PlatformIDs)
{
var newPlat = _gameRepository.GetPlatform(platId);
d.Platforms.Add(new Platform { EntityKey = newPlat.EntityKey });
}
})
И он удаляет исключение «два разных ObjectContexts». Проблема в том, что я получаю следующее исключение, если пытаюсь добавить или присоединить новую сущность Game к своему контексту:
Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом.
К сожалению, исключение не указывает , какой объект это, но я держу пари, что это один из объектов Платформы, так как они уже существуют, и я просто пытаюсь создать новые отношения между два.
Итак, остается вопрос: как, черт возьми, создать новую сущность и заполнить ее свойство EntityCollection <> существующими сущностями? Я не могу быть единственным человеком, который когда-либо хотел создать новую сущность и создать новые отношения «многие ко многим» между ней и существующими сущностями, верно?