Actualizar varias filas en Entity Framework a partir de una lista de identificadores


95

Estoy tratando de crear una consulta para el marco de la entidad que me permitirá tomar una lista de identificadores y actualizar un campo asociado con ellos.

Ejemplo en SQL:

UPDATE Friends
SET msgSentBy = '1234'
WHERE id IN (1, 2, 3, 4)

¿Cómo convierto lo anterior en un marco de entidad?


¿Cuál es su plataforma de base de datos Oracle mysql ..
zee

Mi base de datos es Microsoft SQL
allencoded

Hay dos proyectos de código abierto que permiten esto: EntityFramework.Extended y E ntity Framework Extensions .
Peter Kerr

La única respuesta correcta a esto es: no puedes. Claro, puede extraer todos los correos Friendelectrónicos coincidentes de la base de datos y actualizar su propiedad msgSentByy guardar los cambios. Pero EF disparará UPDATEdeclaraciones para cada registro individual. Eso no es en absoluto lo mismo que una actualización masiva de una declaración. Como se dijo, busque una biblioteca de terceros que ofrezca actualizaciones masivas.
Gert Arnold

Respuestas:


167

algo como abajo

var idList=new int[]{1, 2, 3, 4};
using (var db=new SomeDatabaseContext())
{
    var friends= db.Friends.Where(f=>idList.Contains(f.ID)).ToList();
    friends.ForEach(a=>a.msgSentBy='1234');
    db.SaveChanges();
}

ACTUALIZAR:

puede actualizar varios campos como se muestra a continuación

friends.ForEach(a =>
                      {
                         a.property1 = value1;
                         a.property2 = value2;
                      });

¿Puedo actualizar más de un campo en el foreach anterior que acaba de enviar, que es exactamente lo que pedí? ¿Solo tienes curiosidad por saber si puedes hacer más? Tampoco parece que SubmitChanges funcione del todo. Estoy usando el último marco de entidad. ¿Quizás SaveChanges ()?
codificado allencoded

10
ForEaches un método activado List, y generalmente no se recomienda su uso porque no es una forma de programación muy funcional. Simplemente use foreach (el operador) como una persona normal.
BlueRaja - Danny Pflughoeft

55
El uso de esta solución genera una consulta de actualización para cada elemento de la lista. ¿Hay alguna manera de hacer que EF haga solo una consulta como en la pregunta? ( UPDATE SomeTable SET SomeField = SomeValue WHERE Id IN (...))
RamNow

19
Tenga en cuenta que esta es una forma bastante ineficaz de hacerlo desde la perspectiva de la base de datos. Esto no solo emite una gran declaración de selección que involucra cada fila de la tabla Amigos, sino que emite un comando UPDATE por separado para cada registro que se actualiza. Entonces, en lugar de emitir un comando, puede emitir muchos comandos, además de transmitir una gran cantidad de datos de su base de datos.
d512

1
@ShekharPankaj, básicamente lo que quieres hacer es emitir un comando SQL como "ACTUALIZAR Amigos SET msgSentBy = '1234' DONDE ID EN (1, 2, 3, 4)". No creo que EF tenga apoyo directo para hacer eso. Creo que hay algunas soluciones de terceros para esto ( stackoverflow.com/questions/12751258/batch-update-delete-ef5 ) pero no las he usado. Las otras opciones son utilizar ADO.NET sin procesar en lugar de EF.
d512

-1
var idList=new int[]{1, 2, 3, 4};
var friendsToUpdate = await Context.Friends.Where(f => 
    idList.Contains(f.Id).ToListAsync();

foreach(var item in previousEReceipts)
{
  item.msgSentBy = "1234";
}

Puede usar foreach para actualizar cada elemento que cumpla con su condición.

Aquí hay un ejemplo de una manera más genérica:

var itemsToUpdate = await Context.friends.Where(f => f.Id == <someCondition>).ToListAsync();

foreach(var item in itemsToUpdate)
{
   item.property = updatedValue;
}
Context.SaveChanges()

En general, lo más probable es que utilice métodos asincrónicos con await for db queries.


No veo cómo esto agrega nada a la respuesta existente. Básicamente, simplemente lo repite.
Gert Arnold

la principal diferencia es usar foreach en lugar de friends.ForEach
Raphael Pinel hace
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.