删除EF中多对多关系中选定的关系?

发布于 2024-10-21 20:37:09 字数 1131 浏览 1 评论 0原文

在 SQL 中,我有:

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

在我的 EF 层中,它转换为:

[Bands] * ---- * [Genres]

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

In SQL, I have:

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

In my EF layer, it translates to:

[Bands] * ---- * [Genres]

(BandsGenres is BandId and GenreId)

My problem is, I can't seem to figure out how to delete just the selected relationships I need. Basically, I'm trying to update a list of type Genre for a band. A list of Guids is passed in and I'm able to get those using joins. However, the .Remove() method isn't removing the old genres and adding the new ones. I tried using .Attach(g) and .DeleteObject(g) but that removed the actual Genre (from Genres) instead of just the relationship.

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

How can I delete/add or update my list of genre relationships for a band, given a list of genre IDs? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2024-10-28 20:37:09

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

首先,您不需要连接来获取 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; Genres 可能有点误导,因为它实际上是 Guid 的集合,而不是 Genre 对象的集合。因此,我将其命名为 newGenreIds 以与您的 Guid bandId 变量名称保持一致。

If I understand your problem correcly, the genres collection contains all the Genre objects that should be in the Band genre list as a result of running the UpdateBandGenres method (and not just the list to add or list to delete). In that case the simplest would be removing all the genres from the collection and adding all the genres with the Guids from your genres collection.

First of all, you don't need joins to grab your newGenres:

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

Secondly, you need to fetch the Band object, since modifying its Genres collection will tell EF to modify the BandGenres table in SQL:

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

After that you can clear the band.Genres collection and add the newGenres on top. As a result you code will look like:

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

Btw, I'd also recommend being consistent with naming your variables - e.g. IEnumerable<Guid> genres might be a bit misleading, since it's actually a collection of Guids, and not a collection of Genre objects. Therefore I named it newGenreIds to be consistent with your Guid bandId variable name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文