Saltar al contenido

Entity Framework actualiza / inserta varias entidades

Solución:

Para EFCore, puede usar esta biblioteca:
https://github.com/borisdj/EFCore.BulkExtensions

Y para EF 6 este:
https://github.com/TomaszMierzejowski/EntityFramework.BulkExtensions

Ambos se están extendiendo DbContext con operaciones Bulk y tienen la misma sintaxis llamada:

context.BulkInsert(entitiesList);
context.BulkUpdate(entitiesList);
context.BulkDelete(entitiesList);

La versión EFCore tiene adicionalmente BulkInsertOrUpdate método.

  1. Suponiendo que las clases en apiData son las mismas que sus entidades, debería poder usar Attach(newAccount, originalAccount) para actualizar una entidad existente.
  2. Para insertos a granel que uso AddRange(listOfNewEntitities). Si tiene muchas entidades para insertar, es recomendable agruparlas. También es posible que desee desechar y recrear el DbContext en cada lote para que no utilice demasiada memoria.

    var accounts = new List<Account>();
    var context = new YourDbContext();
    context.Configuration.AutoDetectChangesEnabled = false;
    
    foreach (var account in apiData)
    {
        accounts.Add(account);
        if (accounts.Count % 1000 == 0) 
        // Play with this number to see what works best
        {
            context.Set<Account>().AddRange(accounts);
            accounts = new List<Account>();
            context.ChangeTracker.DetectChanges();
            context.SaveChanges();
            context?.Dispose();
            context = new YourDbContext();
        }
    }
    
    context.Set<Account>().AddRange(accounts);
    context.ChangeTracker.DetectChanges();
    context.SaveChanges();
    context?.Dispose();
    

Para actualizaciones masivas, no hay nada integrado en LINQ to SQL. Sin embargo, existen bibliotecas y soluciones para abordar esto. Consulte, por ejemplo, aquí para obtener una solución utilizando árboles de expresión.

Lista frente a diccionario

Verifica en una lista cada vez si la entidad existe, lo cual es malo. En su lugar, debería crear un diccionario para mejorar el rendimiento.

var existingAccounts = _accountRepository.GetAllList().ToDictionary(x => x.AccountID);

Account existingAccount;

if(existingAccounts.TryGetValue(account.AccountId, out existingAccount))
{
    // ...code....
}

Agregar frente a AddRange

Debe tener en cuenta el rendimiento de Agregar frente a AddRange cuando agrega varios registros.

  • Agregar: Detección de llamadas Cambios después de agregar cada registro
  • AddRange: Call DetectChanges después de agregar todos los registros

ingrese la descripción de la imagen aquí

Entonces, en 10,000 entidades, el método Agregar ha tomado 875 veces más tiempo para agregar entidades en el contexto de manera simple.

Arreglarlo:

  1. Crear una lista

  2. AÑADIR entidad a la lista
  3. USE AddRange con la lista
  4. Guardar cambios
  5. ¡Hecho!

En su caso, deberá crear un método InsertRange en su repositorio.

EF extendido

Tienes razón. Esta biblioteca actualiza todos los datos con el mismo valor. Eso no es lo que busca.

Descargo de responsabilidad: Soy el propietario del proyecto Entity Framework Extensions

Esta biblioteca puede adaptarse perfectamente a su empresa si desea mejorar drásticamente su rendimiento.

Puede realizar fácilmente:

  • BulkSaveChanges
  • BulkInsert
  • Actualización masiva
  • BulkDelete
  • BulkMerge

Ejemplo:

public void ProcessApiData(List<Account> apiData)
{
    // Insert or Update using the primary key (AccountID)
    CurrentUnitOfWork.BulkMerge(apiData);
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *