Удалите из нескольких таблиц (linq к sql)

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

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

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

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

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

6
задан Sam 26 October 2014 в 18:45
поделиться

2 ответа

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

6
ответ дан 10 December 2019 в 00:37
поделиться

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

С другой стороны, если данных ожидается много, например, пользователь форума имеет множество сообщений, комментариев, избранного, закладок и т.д., то я рекомендую использовать хранимую процедуру, которая берет идентификатор пользователя и делает все остальное по мере необходимости. Проблема заключается в том, что для каждой совпадающей записи выполняется один оператор delete для каждой записи . Именно это приводит к более низкой производительности, чем оператор 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.

2
ответ дан 10 December 2019 в 00:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: