Como proceder à actualização em massa dos registos no quadro de entidades?

Estou a tentar actualizar os registos em massa usando o sistema de entidades. Tentei o quadro de entidades.Método Extensions Update.

o método Update é capaz de actualizar a granel para um conjunto de registos com o mesmo conjunto de valores de actualização.

exemplo:

           Id -  Quantity
Record 1 - A  -  10
Record 2 - B  -  20
Record 3 - C  -  30

podemos actualizar todos os registos acima por simples chamada

Records.Update(new => Record { Quantity = 100 });

Como posso actualizar a granel cada registo com quantidades diferentes usando Entityframework.Extensions ou em qualquer outra abordagem, que complete a actualização a granel mais rapidamente?

Author: S.Akbari, 2017-05-26

4 answers

Se não quiser usar uma declaração SQL, pode usar o método Attach para actualizar uma entidade sem ter de a carregar primeiro:

using (myDbEntities db = new myDbEntities())
{
    try
    {
      //disable detection of changes to improve performance
      db.Configuration.AutoDetectChangesEnabled = false;

      //for all the entities to update...
      MyObjectEntity entityToUpdate = new MyObjectEntity() {Id=123, Quantity=100};
      db.MyObjectEntity.Attach(entityToUpdate);

      //then perform the update
      db.SaveChanges();
    }
    finally
    {
      //re-enable detection of changes
      db.Configuration.AutoDetectChangesEnabled = true;
    }
}
 10
Author: Grégory Bourgin, 2017-05-31 12:56:33

Utilizar ExecuteSqlCommand:

using (yourDbEntities db = new yourDbEntities())
{
    db.Database.ExecuteSqlCommand("UPDATE YourTABLE SET Quantity = {0} WHERE Id = {1}", quantity, id);
}

Ou ExecuteStoreCommand:

yourDbContext.ExecuteStoreCommand("UPDATE YourTABLE SET Quantity = {0} WHERE Id = {1}", quantity, id);
 8
Author: S.Akbari, 2017-05-26 07:37:26

A actualização a granel pode ser feita em três passos com EF simples em vez de métodos de extensão separados : -

  • carrega todas as entidades primeiro.
  • para cada entidade e alterar os seus valores de campo.
  • Depois de cada gravação, o contexto muda uma vez.

Isto irá enviar várias consultas de actualização em um único lote.

 0
Author: Jaswinder, 2017-05-29 16:52:35
Estou inclinado a dizer que a questão aqui não é o quadro de direitos, mas a expectativa de como actualizar os registos no SQL. Se você tiver 50 registros e quiser mudar o campo de quantidade em todos eles para um novo valor único, então você precisará usar 50 comandos. AFAIK, SQL simplesmente não tem um mecanismo para entender como atualizar esses registros sem um comando individual para cada registro. Esta limitação passa então para a EF. Dito isto, há algumas maneiras de poderia tentar obter algum desempenho com a atualização de muitos registros:
  • actualização do Lote - como várias outras respostas mencionaram, pode usar uma actualização do lote onde envia várias declarações de actualização de uma vez num único comando para SQL.
  • o Agrupamento de chaves - SQL faz um grande trabalho ao actualizar várias linhas com um único comando de actualização, se quiser definir os campos com o mesmo valor em todos os registos correspondentes na pesquisa. Você pode usar isso a seu favor se você pode agrupar as quantidades que você precisa atualizar. Por exemplo, se você sabe que você precisa atualizar 150 registros para a quantidade 100, você pode executar isso como uma única consulta de atualização com uma cláusula onde para incluir todos os IDs pertinentes.
  • arquivos XML: ( - SQL tem um monte de comandos incorporados para lidar com XML. Você poderia, poderia, usar um comando como UPDATE TBL SET TBL.QUANTITY = XMLTBL.QUANTITY FROM OPENXML(@idoc, '/ROOT/Items',1). Ver https://docs.microsoft.com/en-us/sql/t-sql/functions/openxml-transact-sql para mais informacao.
Parte da questão é saber se é importante actualizar os registos o mais depressa possível. É claro que todos queremos que nossas consultas sejam rápidas, mas se tivermos que implementar algo janky para obter esse desempenho pode não valer a pena a longo prazo. Por exemplo, você poderia executar a atualização em uma linha de fundo para que não seja bloqueado?
 0
Author: KingOfTheWood, 2017-05-30 13:37:42