Добавить / удалить много-много ассоциаций в Entity Framework - PullRequest
6 голосов
/ 19 июля 2011

В моей базе данных есть три таблицы:

Пользователи

  • ID
  • Имя пользователя
  • Пароль

Роли

  • ID
  • Имя
  • Описание

UserRoles

  • ИД пользователя
  • 1028 * Идентификатор роли *

UserRoles - это таблица соответствия, которая имитирует отношения многие ко многим. Добавление записей в эту таблицу позволяет связать записи в пользователях и ролях. Моя проблема в том, что в Entity Framework он правильно интерпретирует это как отношение «многие ко многим» и абстрагирует эту справочную таблицу.

Это прекрасно работает большую часть времени, но я не уверен, что делать, когда я хочу добавить / удалить записи из этой таблицы поиска. Я могу удалять роли или пользователей, но это фактически удаляет объекты, а не только их связь друг с другом.

Мне известен один вариант добавления фиктивного столбца в таблицу поиска UserRoles. Это заставит Entity Framework превратить таблицу поиска в полноценную сущность, что позволит мне добавлять и удалять их как отдельные объекты. Но мне не нужна фиктивная колонна, и это похоже на взлом. Я ищу лучшие предложения.

Ответы [ 3 ]

7 голосов
/ 19 июля 2011

Это должно выглядеть примерно так:

Удалить связь

user.Roles.Remove(existingRoleEntity);

Добавить отношение

user.Roles.Add(existingRoleEntity);
3 голосов
/ 19 июля 2011

Вы можете использовать свойства навигации для объектов:

(при условии, что вы - объект пользователя):

using (var db = new UserEntities())
{
    Role roleToRemove = db.Roles.Single(SelectRoleHere);
    User user = db.Users.Single(SelectUserHere);
    user.Roles.Remove(roleToRemove);
    db.SaveChanges();
}

РЕДАКТИРОВАТЬ - Добавлены SaveChanges на основе Slaumaкомментарии.

1 голос
/ 19 июля 2011

Я уже решил эту проблему, просто добавив столбец автоинкремента идентификатора закрытого ключа в таблицу поиска, так как Entity Framework всегда будет скрывать таблицы поиска, содержащие только 2 столбца с внешними ключами, в конечных таблицах.Иногда вам нужно добавить запись поиска непосредственно через Entity Framework, и это поможет вам достичь этого.

Обновление от автора вопроса

Я просто хотел предоставить обновление для моей собственной реализацииэтот ответЯ добавил столбец идентификаторов в таблицу поиска и создал уникальный ключ для двух столбцов внешнего ключа, чтобы предотвратить повторяющиеся записи отношений в таблице.Моя модель теперь выглядит следующим образом:

http://www.codetunnel.com/content/images/ManyToManyDynamic.jpg

Единственное, что отстой, - это получить коллекцию всех связанных ролей, которые я должен сделать:

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);

Это немного больше работы, но если нет эквивалента user.Roles.Remove(role) (что-то вроде user.Roles.Associate(existingRoleEntity)), тогда это мой единственный вариант.

Обновление:

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);

Может бытьдостигается с помощью:

IEnumerable<int> roleIDs = myUser.UserRoles.Select(r => r.RoleID);
IEnumerable<Role> roles = Entityies.Roles.Where(r => roleIDs.Contains(r.roleID);

Вы всегда можете использовать открытый частичный класс , чтобы расширить User, чтобы иметь свойство для возврата всех ролей, используя описанное выше.Нажмите на ссылку, чтобы узнать подробности о public partial class, которые я дал по другому вопросу.

...