2009-12-23 9 views
8

Tengo 2 clases de Linq2Sql: Parent y Child. Quiero hacer cosas como eliminar todos los hijos de un padre o actualizar todos los registros secundarios. En SQL habría escrito:¿Cómo ejecutar una consulta de actualización/eliminación masiva en Linq?

delete Child where ParentID = @p 

o

update Child set Val = Val+1 where ParentID = @p 

puedo hacer esto en LINQ la forma en la fuerza bruta dentro de la clase Parent:

Children.ToList().ForEach(c => c.DeleteOnSubmit()); // DeleteOnSubmit is my own method 

y

Children.ToList().ForEach(c => c.Val++); 

Pero dado Li Penalización inherente al rendimiento de nq en ciclos ForEach, esta parece ser una forma muy ineficiente de hacer las cosas. ¿Hay alguna forma de lograr el fin deseado que disparará exactamente una consulta?

Respuesta

9
+0

+1 ¡Guau, este es un gran enlace! Estoy a punto de cambiar de opinión sobre el crédito de respuesta ... –

+0

¡Sí, la solución de Terry Aney es genial! ¡Responde crédito para ti! –

+2

@Shaul Esta podría ser una gran respuesta ahora, pero las respuestas de solo el enlace tienen este problema que tarde o temprano se vuelven inútiles, porque el recurso externo ya no se puede alcanzar. Siempre es mejor escribir al menos una parte de la solución aquí, de modo que estará disponible mientras SO viva. – jahu

14

Para estos casos, puede usar el DataContext.ExecuteCommand method para ejecutar directamente SQL en su base de datos. Por ejemplo:

dataContext.ExecuteCommand("delete Child where ParentID = {0}", parentId); 
+1

Uf, eso es feo. ¿No usa SQL literal la mitad del propósito de usar Linq? –

+3

@Shaul, en su mayor parte, sí, pero LINQ-To-SQL no es compatible con la actualización/eliminación masiva, por lo que esa es su opción. Otra opción sería un procedimiento almacenado. –

+0

Oh, bueno, si no hay otra alternativa, supongo que recibes una respuesta de crédito ... –

-1

probar este

_db.tblStockAllocationEurails.Where(t => t.StockNo >= From && t.StockNo <= To).ToList().ForEach(t => t.StatusID = NewGuid); 
_db.SaveChanges(); 
+0

-1, lo siento, pero esta es una respuesta terrible. –

1

actualizar y eliminar

Una limitación actual del marco de la entidad es que con el fin de actualizar o eliminar una entidad que tiene que recuperar primero en la memoria. Además, para las eliminaciones individuales, el objeto debe recuperarse antes de que pueda eliminarse y requiera dos llamadas a la base de datos. Para superar este problema, debemos ampliar el marco de entidad actual utilizando EntityFramework.Extended. EntityFramework.Extended tiene funciones útiles como Actualización por lotes y Eliminar, Registro de auditoría, Caché de resultados de consulta, Consultas futuras. La actualización y eliminación de lotes elimina la necesidad de recuperar y cargar una entidad antes de modificarla. Aquí hay algunas líneas de código para demostrar cómo eliminar, actualizar.

instalar a través de Nuget

PM> Install-Package EntityFramework.Extended

Actualizar

Escenario: Actualizar los clientes que tienen EE.UU. país. Si hacemos esto sin ninguna extensión, tenemos que buscar a todos los clientes que tengan el país USA, modificar la lista y actualizarla usando loops. Al utilizar Entity Framework. Extendido, no es necesario que obtengamos la lista de clientes, simplemente agreguemos el estado, establezcamos los datos de actualización y ejecutemos la consulta.

static void Main(string[] args) 
{ 
    using(var db = new DataContext()) 
    { 
     db.Customers.Where(c => c.Country == "USA").Update(c => new Customer() 
     { 
      Country = "IN" 
     }); 

     foreach(var customer in db.Customers.ToList())  
     { 
      Console.WriteLine("CustomerInfo - {0}-{1}-{2}", customer.Name, customer.Country, customer.Status); 
     } 
    } 

    Console.ReadLine(); 
} 

https://code.msdn.microsoft.com/entity-framework-batch-994cd739

Cuestiones relacionadas