2010-03-03 16 views
6

Estoy utilizando Linq para SQL para acceder a mi base de datos. Quiero tener una función de 'eliminar cuenta' que básicamente elimina todos los registros en todas las tablas que pertenecen a un usuario dado. ¿Cuál sería la forma más eficiente de hacer esto?Eliminar de varias tablas (linq a sql)

La eliminación tiene que ocurrir en un cierto orden, de lo contrario hay errores de integridad de clave externa. Puedo hacer esto manualmente desde la base de datos, y mi suposición sería simplemente emular eso en L2S, p. (Pseudo código)

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

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

Sin embargo, estoy seguro de que no es la forma más eficiente de eliminación de los registros.

+0

Si pudiera hacer una pregunta. ¿Por qué hacer esto desde linq-a-sql en lugar de con un SP o algo similar en el db mismo? De esta forma puede controlar el pedido, proporcionar otras funcionalidades, etc. Parece engorroso hacerlo con l2s en lugar de utilizar la funcionalidad incorporada del db. – GrayWizardx

+0

Nunca he usado SQL directamente, así que pensé que sería más fácil de Linq. Sin embargo, no me importa usar SQL con algunas sugerencias :) –

Respuesta

6

La solución más simple es simplemente crear una restricción FOREIGN KEY con ON DELETE CASCADE en la base de datos. De esta forma, no tendrá que preocuparse por el orden de borrado ni por ningún otro motivo. Simplemente borre el registro de la cuenta y listo.

2

Si hay un puñado de tablas y los datos que pertenecen al usuario no son mucho, entonces podría emitir los comandos en LINQ to SQL. Por "no es mucho" me refiero a algunos registros que apenas cambian, como información de inicio de sesión, información de dirección y preferencias. Lo ideal sería mantener toda esta lógica unida para garantizar que los pasos se ejecuten siempre en el orden deseado. Incluso si este es el caso, aún se puede usar un procedimiento almacenado.

Por otro lado, si se espera que los datos sean muchos, como un usuario de foro que tenga varias publicaciones, comentarios, favoritos, marcadores, etc., le recomiendo usar un procedimiento almacenado que tome la ID del usuario y hace el resto según sea necesario. La preocupación es que se emite una única declaración de eliminación para cada registro coincidente. Eso es lo que causa un peor rendimiento que una declaración de eliminación que borra todos los registros asociados con la identificación del usuario en una declaración.

Opción # 1: Utilice un procedimiento almacenado

Puede asignar el procedimiento almacenado para su DataContext, lo que le da la posibilidad de utilizarlo como dc.DeleteUserAccount(userId). Scott Gu tiene una excelente publicación de blog que puede ayudarlo a comenzar: LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures).

Opción # 2: Uso de lotes de Terry Aney código de actualización de

Terry Aney tiene una gran entrada de blog que habla de su experiencia en el desarrollo de la capacidad de actualización por lotes y borrar con LINQ to SQL de una manera eficiente. En lugar de generar una sola declaración de actualización/eliminación para cada registro coincidente, el código generará una sola declaración para todos los registros de la forma en que normalmente los escribiríamos. La publicación y el código se pueden encontrar aquí: Batch Updates and Deletes with LINQ to SQL.

Opción # 3: Utilice el método DataContext.ExecuteCommand

El DataContext.ExecuteCommand method se puede utilizar para ejecutar SQL directamente, tales como:

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

Aviso el uso de {0} y {1} que permiten la entrada para ser parametrizado. Use esto en lugar de concatenar para evitar ataques de inyección SQL.

Si vas a utilizar esto, entonces también puedes ir con la opción n. ° 1.

+0

¡Gracias por la respuesta! Por el momento, la información del usuario no es mucho, pero podría aumentar con el tiempo. Examinaré ir al formato de proc almacenado. –

2

Aaronaught es correcto, pero para aquellos de ustedes que se preguntan cómo hacerlo en Microsoft SQL Server Management Studio he adjuntado una captura de pantalla que describe dónde hacerlo.

Haga clic con el botón derecho en la tabla que desee, haga clic en el botón Relationships, haga clic en una de las relaciones y expanda INSERT And UPDATE Spesification en Table designer.

Luego elija Delete rule = Cascade y listo. Cada vez que elimine un registro de esta tabla, también se borrarán todos los elementos de clave externa que haya seleccionado en cascada.

alt text