2011-03-13 250 views
0

在SQL中,我有:在EF中删除多对多关系中的选定关系?

[波段] 1 ---- * [BandsGenres] * ---- 1 [流派]

在我的EF层,将其转换为:

[波段] * ---- * [文体]

(BandsGenres是BandId和GenreId)

我的问题是,我似乎无法弄清楚如何删除只是我需要的选定关系。基本上,我正在尝试更新乐队类型类型的列表。一个Guid列表被传入,我可以使用连接。但是,.Remove()方法不会删除旧的流派并添加新的流派。我尝试使用.Attach(g)和.DeleteObject(g),但删除了实际流派(来自流派),而不仅仅是关系。

public void UpdateBandGenres(Guid bandId, IEnumerable<Guid> genres) 
{ 
    using (var ctx = new OpenGroovesEntities()) 
    { 
     var newGenres = from g in ctx.Genres 
         join t in genres on g.GenreId equals t 
         select g; 

     //var bandGenres = ctx.Genres.Include("Bands").Where(g => g.Bands.Any(b => b.BandId == bandId)); 
     var bandGenres = ctx.Bands.SingleOrDefault(b => b.BandId == bandId).Genres; 

     bandGenres.ToList().ForEach(g => 
     { 
      bandGenres.Remove(g); 
     }); 

     newGenres.ToList().ForEach(g => bandGenres.Add(g)); 

     ctx.SaveChanges(); 
    } 
} 

如何在给定流派ID列表的情况下删除/添加或更新我的乐队的流派关系列表?谢谢。

回答

3

如果我正确地将了解你的问题,genres集合包含所有Genre对象应在Band类型列表,运行UpdateBandGenres方法(而不是仅仅在列表中添加或删除列表中的)的结果。在这种情况下,最简单的方法是从集合中删除所有流派,并添加您的genres集合中的Guid的所有流派。

首先,你不需要加入到抢你newGenres

var newGenres = ctx.Genres.Where(g => genres.Contains(g.GenreId)); 

其次,你需要获取Band对象,因为修改其Genres集合会告诉EF修改BandGenres表SQL:

Band band = ctx.Bands.SingleOrDefault(b => b.BandId == bandId); 

之后,你可以清除band.Genres收集和顶部添加newGenres。因此,你的代码将如下所示:

public void UpdateBandGenres(Guid bandId, IEnumerable<Guid> newGenreIds) 
{ 
    using (var ctx = new OpenGroovesEntities()) 
    { 
     List<Genre> newGenres = ctx. 
           Genres. 
           Where(g => newGenreIds.Contains(g.GenreId)). 
           ToList(); 

     Band band = ctx.Bands.Single(b => b.BandId == bandId); 
     band.Genres.Clear(); 
     newGenres.ForEach(band.Genres.Add); 

     ctx.SaveChanges(); 
    } 
} 

顺便说一句,我还建议与命名变量保持一致 - 例如, IEnumerable<Guid> genres可能有点误导,因为它实际上是一个Guid的集合,而不是一组Genre对象。因此我将其命名为newGenreIds与您的Guid bandId变量名称一致。