【问题标题】:Deleting selected relations in many-to-many relationship in EF?在EF中删除多对多关系中的选定关系?
【发布时间】:2011-03-13 14:08:07
【问题描述】:

在 SQL 中,我有:

[Bands] 1 ---- * [BandsGenres] * ---- 1 [Genres]

在我的 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 列表的情况下,如何删除/添加或更新我的乐队流派关系列表?谢谢。

【问题讨论】:

    标签: c# asp.net linq entity-framework linq-to-entities


    【解决方案1】:

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

    首先,你不需要加入来获取你的newGenres:

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

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

    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&lt;Guid&gt; genres 可能有点误导,因为它实际上是 Guids 的集合,而不是 Genre 对象的集合。因此我将其命名为 newGenreIds 以与您的 Guid bandId 变量名称保持一致。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 2023-01-27
      • 2017-04-17
      相关资源
      最近更新 更多