Entity Framework добавляет проблему во многих сценариях обновления - PullRequest
4 голосов
/ 15 декабря 2011

У меня есть сценарий, в котором я хочу обновить сущность фильма и отношения «многие ко многим» с жанрами.

Свойство навигации Genres в фильме содержит объекты-заглушки Genre, которые содержат только GenreID, поскольку я хочу сохранить запросы к БД для всех жанров.

См. Код ниже, это довольно очевидно. Проблема в том, что мне нужно привязать мои жанры «заглушки» к контексту, чтобы EF изменял только отношение M: M, а не пытался создавать новые записи жанров. Это приводит к ошибке, если жанр уже присоединен к контексту, когда я загружаю текущие жанры фильма. Он не может отслеживать несколько объектов с одинаковыми ключами.

Как с этим обращаться? Есть ли способ проверить, отслеживает ли уже контекст сущность, или есть лучшее решение этой проблемы?

Код ниже:

public override void Update(Movie movie)
        {
            //Backup new genres before clearing genres from movie
            var newGenres = movie.Genres;
            movie.Genres = new List<Genre>();


            _ctx.Entry(movie).State = System.Data.EntityState.Modified;

            //Load movie's current genres from DB and remove them
            _ctx.Entry(movie).Collection(m => m.Genres).Load();
            movie.Genres.Clear();

            //Add new genres to movie
            foreach (var genre in newGenres)
            {
                _ctx.Genres.Attach(genre); //Problem if genre already attached
                movie.Genres.Add(genre);
            }
        }

Спасибо за любую помощь.

1 Ответ

3 голосов
/ 15 декабря 2011

Вы можете попытаться избежать прикрепления заглушек, если объект с таким же ключом уже подключен:

public override void Update(Movie movie)
{
    //Backup new genres before clearing genres from movie
    var newGenres = movie.Genres;
    movie.Genres = new List<Genre>();

    _ctx.Entry(movie).State = System.Data.EntityState.Modified;

    //Load movie's current genres from DB and remove them
    ctx.Entry(movie).Collection(m => m.Genres).Load();
    var currentGenres = movie.Genres.ToList();
    movie.Genres.Clear();

    //Add new genres to movie
    foreach (var genre in newGenres)
    {
        var currentGenre = currentGenres.SingleOrDefault(g => g.Id == genre.Id);
        if (currentGenre != null)
            movie.Genres.Add(currentGenre);
        else
        {
            _ctx.Genres.Attach(genre);
            movie.Genres.Add(genre);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...