Я использую 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);
...
Однако я уверен, что это не самый эффективный способ удалить записи.
Простейшее решение - просто создать ограничение FOREIGN KEY
с ON DELETE CASCADE
в базе данных. Таким образом, вам не нужно беспокоиться о порядке удаления или о чем-то еще. Просто удалите запись об учетной записи, и все готово.
Если есть несколько таблиц и данных, принадлежащих пользователю, немного, то вы можете выполнять команды в 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.