Редактирование записей в таблице ассоциаций в отношении многие ко многим - PullRequest
1 голос
/ 09 мая 2011

Это то, что беспокоило меня некоторое время, и я, наконец, хочу получить ответ на него.

Скажем, у меня есть сотрудники и отделы.Между этими двумя существует связь «многие ко многим» с таблицей ассоциации EmployeeDepartments.

Employees
-------------------
EmployeeID (PK)

Departments
-------------------
DepartmentID (PK)

EmployeeDepartments
-------------------
EmployeeID (FK)
DepartmentID (FK)

У меня есть страница, где пользователь может редактировать сотрудника.Существует список флажков, который показывает все отделы, и отделы, к которым принадлежит сотрудник, будут проверены.Затем пользователь может проверить / снять флажок, к каким отделам принадлежит сотрудник.

Когда я редактирую сотрудника и сохраняю данные, как мне обращаться с этими отделами?

Как яЯ делал это, чтобы удалить каждую запись в таблице EmployeeDepartments для этого сотрудника.И затем для каждого отдела, выбранного пользователем, я добавляю его в EmployeeDepartments.

Это работает, но должен быть более эффективный способ сделать это, это просто кажется неправильным.Если сотрудник находится в 5 отделах, и я собираюсь добавить этого сотрудника в другой отдел, мне придется удалить 5 записей из EmployeeDepartments, а затем добавить 6 записей.

Ответы [ 2 ]

2 голосов
/ 10 мая 2011

Если ваш продукт SQL поддерживает его, вы можете использовать стандартные SQL MERGE. Если ваш продукт SQL - SQL Server, то вам повезло: его MERGE имеет отличное расширение IF NOT MATCHED BY SOURCE, которое позволяет вам DELETE в дополнение к INSERT и UPDATE.

Вот простой пример (например, без ограничения ссылочной целостности):

CREATE TABLE EmployeeDepartments 
(
 EmployeeID INTEGER NOT NULL, 
 DepartmentID INTEGER NOT NULL, 
 UNIQUE (DepartmentID, EmployeeID)
);

INSERT INTO EmployeeDepartments (EmployeeID, DepartmentID)
   VALUES (1, 1), 
          (1, 2);

Скажем, после редактирования вы помещаете значения в промежуточную таблицу:

CREATE TABLE StagingTable 
(
 EmployeeID INTEGER NOT NULL, 
 DepartmentID INTEGER NOT NULL, 
 UNIQUE (DepartmentID, EmployeeID)
);

INSERT INTO StagingTable (EmployeeID, DepartmentID)
   VALUES (1, 1), 
          (1, 3);

На простом английском языке будет вставлена ​​строка {1, 3}, строка {1, 2} будет удалена, а строка {1, 1} останется:

MERGE INTO EmployeeDepartments
   USING StagingTable AS S1 
      ON EmployeeDepartments.EmployeeID = S1.EmployeeID
         AND EmployeeDepartments.DepartmentID = S1.DepartmentID
WHEN NOT MATCHED THEN
   INSERT (EmployeeID, DepartmentID)
      VALUES (EmployeeID, DepartmentID)
WHEN NOT MATCHED BY SOURCE THEN
   DELETE;
2 голосов
/ 10 мая 2011

Просто обработайте изменение дельта.То есть посмотрите на «выбранные» в данный момент элементы, затем элементы для выбора, а затем либо добавьте, либо удалите соответствующие.Это может быть вычислено с использованием заданных операций (которые тривиальны в LINQ).

  1. Удалить элементы в old - new (установить разницу или Except)
  2. Добавить элементы в new - old (установить разницу или Except)
  3. (элементы в new ^ old не должны быть затронуты)

Большая часть этой работы может быть передана в базу данных, если это необходимо,(Удалите, кроме где ... и вставьте, если не существует ... например. Также см. Стандартную инструкцию SQL MERGE и нестандартные эквиваленты и расширения).

Убедитесь, чтоправильно использовать транзакции базы данных для обеспечения согласованности.

Счастливое кодирование.

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