我有一个场景,我希望更新一个电影实体及其与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);
}
}
感谢您的帮助。
答案 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);
}
}
}