Удаление выбранных отношений в отношениях многих ко многим в EF? - PullRequest
0 голосов
/ 13 марта 2011

В SQL у меня есть:

[Полосы] 1 ---- * [BandsGenres] * ---- 1 [Жанры]

В моемСлой EF переводится как:

[Полосы] * ---- * [Жанры]

(BandsGenres - это BandId и GenreId)

Моя проблема в том, что я не могу понять, как удалить только те отношения, которые мне нужны.По сути, я пытаюсь обновить список типа Жанр для группы.Передан список гидов, и я могу получить тех, кто использует соединения.Однако метод .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();
    }
}

Как я могу удалить / добавить или обновить мой список жанровых отношений для группы, учитывая список идентификаторов жанров?Благодаря.

1 Ответ

3 голосов
/ 13 марта 2011

Если я правильно понимаю вашу проблему, коллекция genres содержит все объекты Genre, которые должны быть в списке жанров Band в результате выполнения метода UpdateBandGenres (а не только список для добавленияили список для удаления).В этом случае самым простым будет удаление всех жанров из коллекции и добавление всех жанров с Guid s из вашей коллекции genres.

Прежде всего, вам не нужны объединения для захватаваш 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 s, а не коллекция Genre объектов.Поэтому я назвал его newGenreIds, чтобы он соответствовал вашему Guid bandId имени переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...