实体框架在许多更新方案中都存在问题

时间:2011-12-15 15:36:12

标签: entity-framework entity-framework-4 entity-framework-4.1

我有一个场景,我希望更新一个电影实体及其与Genres的多对多关系。

影片中的导航属性Genres包含仅包含Genre的存根GenreID对象,因为我想保存查询所有类型的数据库。

请参阅下面的代码,它相当自我解释。问题是我需要将我的“Stub”类型附加到上下文中,因此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 个答案:

答案 0 :(得分:3)

如果已经附加了具有相同密钥的实体,您可以尝试避免附加存根:

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);
        }
    }
}