Supresión masiva en LINQ a entidades

¿Hay alguna forma de eliminar por lotes un conjunto de objetos que coincidan con una consulta determinada en LINQ o LINQ-to-Entities? Las únicas referencias que puedo encontrar están desactualizadas, y parece tonto iterar y eliminar manualmente todos los objetos que deseo eliminar.

La pregunta es antigua (antes de que EF5 existiera). Para cualquiera que esté usando EF5, EntityFramework.Extended hace esto en un instante.

Hace un tiempo escribí una serie de blog de 4 partes (Partes 1 , 2 , 3 y 4 ) que cubría la realización de actualizaciones masivas (con un solo comando) en Entity Framework.

Si bien el foco de esa serie era la actualización, definitivamente podría usar los principios involucrados para eliminar.

Entonces deberías poder escribir algo como esto:

 var query = from c in ctx.Customers where c.SalesPerson.Email == "..." select c; query.Delete(); 

Todo lo que necesita hacer es implementar el método de extensión Delete (). Consulte la serie de publicaciones para obtener sugerencias sobre cómo …

Espero que esto ayude

  using (var context = new DatabaseEntities()) { // delete existing records context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId); } 

Las respuestas que estoy viendo aquí son de Linq a Sql

DeleteAllOnSubmit es parte de System.Data.Linq y ITable que es de Linq a Sql

Esto no se puede hacer con Entity Framework.

Habiendo dicho todo eso, todavía no tengo una solución pero publicaré cuando lo haga

Para aquellos que usan EF6 y quieren ejecutar una consulta SQL de fila para su eliminación:

 using (var context = new DatabaseEntities()) { // delete existing records context.Database.ExecuteSqlCommand("DELETE FROM YOURTABLE WHERE CustomerID = @id", idParameter); } 

Sé del método DeleteAllOnSubmit de cualquier contexto de datos que eliminará todos los registros en la consulta. Debe haber cierta optimización subyacente ya que muchos objetos se están eliminando. No estoy seguro sin embargo.

No estoy seguro de lo eficiente que sería, pero podrías intentar algo como esto:

 // deletes all "People" with the name "Joe" var mypeople = from p in myDataContext.People where p.Name == "Joe"; select p; myDataContext.People.DeleteAllOnSubmit(mypeople); myDataContext.SubmitChanges(); 

Podría escribir un proceso almacenado que elimine y llamarlo desde LINQ. En general, una eliminación basada en conjunto es más rápida, pero si afecta a demasiados registros podría causar problemas de locking y es posible que necesite un híbrido de bucles a través de conjuntos de registros (tal vez 2000 a la vez, el tamaño depende del diseño de su base de datos pero 2000 es lugar de inicio si considera que el delte basado en conjunto tarda tanto en afectar el uso de la tabla) para realizar la eliminación.

La eliminación de datos a través de Entity Framework se basa en el uso del método DeleteObject. Puede invocar este método en EntityCollection para la clase de entidad que desea eliminar o en ObjectContext derivado. Aquí hay un ejemplo simple:

 NorthwindEntities db = new NorthwindEntities(); IEnumerable ods = from o in db.Order_Details where o.OrderID == 12345 select o; foreach (Order_Detail od in ods) db.Order_Details.DeleteObject(od); db.SaveChanges(); 

Haría algo como:

 var recordsToDelete = (from c in db.Candidates_T where c.MyField == null select c).ToList(); if(recordsToDelete.Count > 0) { foreach(var record in recordsToDelete) { db.Candidate_T.DeleteObject(record); db.SaveChanges(); } } 

No creo que haya una manera de hacerlo sin un bucle, ya que Entity Framework funciona con Entidades y la mayoría de las veces, esto significa la recolección de objetos.

En este ejemplo, obtengo los registros para eliminar, y uno a uno los adjunta al conjunto de resultados y luego solicito que se eliminen. Entonces tengo 1 guardar cambios.

  using (BillingDB db = new BillingDB()) { var recordsToDelete = (from i in db.sales_order_item where i.sales_order_id == shoppingCartId select i).ToList(); if(recordsToDelete.Count > 0) { foreach (var deleteSalesOrderItem in recordsToDelete) { db.sales_order_item.Attach(deleteSalesOrderItem); db.sales_order_item.Remove(deleteSalesOrderItem); } db.SaveChanges(); } } 
  context.Entity.Where(p => p.col== id) .ToList().ForEach(p => db.Entity.DeleteObject(p)); 

este es el método más rápido para borrar el registro de DB usando EF

RemoveRange se introdujo en EF6, puede eliminar una lista de objetos. Muy facil.

 var origins= (from po in db.PermitOrigins where po.PermitID == thisPermit.PermitID select po).ToList(); db.PermitOrigins.RemoveRange(origins); db.SaveChanges();