Удалить из нескольких таблиц (linq to sql) - PullRequest
6 голосов
/ 03 марта 2010

Я использую Linq to SQL для доступа к моей базе данных. Я хочу иметь функцию «удалить учетную запись», которая в основном избавляет от всех записей во всех таблицах, которые принадлежат данному пользователю. Что было бы наиболее эффективным способом сделать это?

Удаление должно происходить в определенном порядке, в противном случае возникают ошибки целостности внешнего ключа. Я могу сделать это вручную из базы данных, и я предпочел бы просто эмулировать это в L2S, например. (псевдокод)

var tb1del = From Table1 Where userId == userIdToDelete;
mydatacontext.Table1.deleteonsubmit(tb1del);

var tb1de2 = From Table1 Where userId == userIdToDelete;
mydatacontext.Table2.deleteonsubmit(tb1de2);
...

Однако я уверен, что это не самый эффективный способ удаления записей.

Ответы [ 3 ]

6 голосов
/ 03 марта 2010

Самое простое решение - просто создать ограничение FOREIGN KEY с ON DELETE CASCADE в базе данных. Таким образом, вам не нужно беспокоиться о порядке удаления или о чем-либо еще. Просто удалите запись учетной записи, и все готово.

2 голосов
/ 22 сентября 2010

Aaronaught правильно, но для тех из вас, кто интересуется, как это сделать в Microsoft SQL Server Management Studio, я приложил скриншот, в котором описано, где это сделать.

Щелкните правой кнопкой мыши по нужной таблице, нажмите кнопку Relationships, выберите одно из отношений и разверните INSERT And UPDATE Spesification в Table designer.

.

Затем выберите Delete rule = Cascade и все готово. Каждый раз, когда вы удаляете запись из этой таблицы, все элементы внешнего ключа, которые вы выбрали каскадно, будут также удаляться.

alt text

2 голосов
/ 03 марта 2010

Если имеется несколько таблиц и данных, принадлежащих пользователю, немного, вы можете выполнить команды в LINQ to SQL. Под «не очень» я подразумеваю несколько записей, которые практически не меняются, таких как информация для входа в систему, адрес и информация В идеале вы хотели бы сохранить всю эту логику вместе, чтобы гарантировать, что шаги всегда выполняются в намеченном порядке. Даже если это так, хранимая процедура все еще может использоваться.

С другой стороны, если ожидается, что данных будет много, например, пользователь форума, у которого есть несколько постов, комментариев, избранных, закладок и т. Д., Тогда я рекомендую использовать хранимую процедуру, которая принимает идентификатор пользователя и остальное по мере необходимости. Проблема заключается в том, что для каждой соответствующей записи выдается один оператор удаления . Именно это приводит к более низкой производительности, чем оператор delete, который удаляет все записи, связанные с идентификатором пользователя, в одном операторе. Вариант № 1: использовать хранимую процедуру

Вы можете отобразить хранимую процедуру в свой DataContext, что дает вам возможность использовать ее как dc.DeleteUserAccount(userId). У Скотта Гу есть отличное сообщение в блоге, которое поможет вам начать: LINQ to SQL (Часть 6 - Получение данных с использованием хранимых процедур) .

Вариант № 2: используйте код пакетного обновления Терри Ани

У Терри Ани есть отличное сообщение в блоге, в котором рассказывается о его опыте разработки возможности пакетного обновления и удаления с помощью LINQ to SQL. Вместо генерации одного оператора обновления / удаления для каждой совпадающей записи, код будет генерировать один оператор для всех записей так, как мы обычно пишем их. Почту и код можно найти здесь: Пакетное обновление и удаление с LINQ to SQL .

Вариант № 3: Использовать метод DataContext.ExecuteCommand

Метод DataContext.ExecuteCommand может использоваться для непосредственного выполнения SQL, например:

int affectedRecords = 
    dc.ExecuteCommand("Update Person SET FirstName = {0} WHERE FirstName = {1}", "Foo", "Bar");

Обратите внимание на использование {0} и {1}, которые позволяют параметризовать ввод. Используйте это вместо объединения, чтобы предотвратить атаки SQL-инъекций.

Если вы собираетесь использовать это, то вы могли бы также пойти с опцией # 1.

...