🔄 BulkSynchronize en EF Core es una extensión de la librería Entity Framework Extensions de ZZZ Projects que permite integrar datos externos con tu base de datos en una sola operación: inserta lo que no existe, actualiza lo que cambió y elimina lo que sobra, sin escribir lógica repetitiva. Es ideal para flujos de integración de datos con archivos Excel, JSON de APIs o sistemas de terceros.
🧬 Ejemplo práctico
👉 Haz clic en este enlace para probar el ejemplo: dotnetfiddle.net/v4KQSX.
Imagina que recibes periódicamente un catálogo de productos desde un sistema externo (nombre, precio y categoría). Con BulkSynchronize puedes poner al día tu tabla en un solo paso: nuevos → se insertan; existentes → se actualizan; obsoletos → se eliminan automáticamente.
💻 Demo interactiva (.NET Fiddle): edita y ejecuta el ejemplo sin salir del navegador.
⚙️ Instalación rápida
Antes de comenzar con BulkSynchronize, instala el paquete oficial y agrega el using correspondiente en tu proyecto EF Core.
// .NET CLI
dotnet add package Z.EntityFramework.Extensions.EFCore
// Package Manager Console
PM> NuGet\Install-Package Z.EntityFramework.Extensions.EFCore
// Using requerido
using Z.EntityFramework.Extensions;
🧩 Ejemplo práctico en código de BulkSynchronize en EF Core
El siguiente ejemplo muestra cómo usar BulkSynchronize en EF Core para integrar una lista externa de productos con tu base de datos. Los registros nuevos se insertan, los existentes se actualizan y los que ya no estén en la lista se eliminan automáticamente, manteniendo la base de datos perfectamente sincronizada.
➡️ Versión sincrónica
// @nuget: Z.EntityFramework.Extensions.EFCore
using Z.EntityFramework.Extensions;
var externos = new List<Producto>
{
new Producto { Nombre = "Teclado mecánico", CategoriaId = 1, Precio = 59.90m },
new Producto { Nombre = "Mouse inalámbrico", CategoriaId = 1, Precio = 29.90m },
new Producto { Nombre = "Monitor 24 pulgadas", CategoriaId = 2, Precio = 149.00m }
};
using (var context = new AppDbContext())
{
context.BulkSynchronize(externos, options =>
{
options.ColumnPrimaryKeyExpression = x => new { x.Nombre, x.CategoriaId };
});
}
➡️ Versión asíncrona
// @nuget: Z.EntityFramework.Extensions.EFCore
using Z.EntityFramework.Extensions;
var externos = new List<Producto>
{
new Producto { Nombre = "Teclado mecánico", CategoriaId = 1, Precio = 59.90m },
new Producto { Nombre = "Mouse inalámbrico", CategoriaId = 1, Precio = 29.90m },
new Producto { Nombre = "Monitor 24 pulgadas", CategoriaId = 2, Precio = 149.00m }
};
using (var context = new AppDbContext())
{
await context.BulkSynchronizeAsync(externos, options =>
{
options.ColumnPrimaryKeyExpression = x => new { x.Nombre, x.CategoriaId };
});
}
🌎 Contexto práctico de BulkSynchronize en EF Core
Cuando trabajas con datos que vienen de fuentes externas (Excel/CSV, APIs, sistemas de terceros) BulkSynchronize en EF Core te ahorra bucles y comparaciones manuales. Estos son escenarios típicos donde brilla:
- Alineación de catálogos (productos, clientes, precios). Recibes una lista “maestra” periódica y necesitas reflejarla en BD: nuevos → insert, existentes → update, obsoletos → delete.
- Integración por lotes (jobs nocturnos / ETL ligero). Procesos programados que actualizan miles de filas en una sola operación, dentro de transacción.
- APIs externas (JSON masivo). Tu app recibe “snapshots” de entidades y debes hacer un put-your-DB-in-sync eficiente.
- Migraciones y limpieza. Normalizas datos, renuevas catálogos o marcas/eliminas registros que ya no aplican.
- Backoffice y paneles operativos. Equipos no técnicos suben Excel/CSV y el sistema sincroniza en un clic, sin código extra.
🧭 ¿Qué es BulkSynchronize en EF Core y por qué usarlo?
BulkSynchronize() integra una lista externa con tu tabla en una sola pasada: inserta lo que no existe, actualiza lo que cambió y elimina lo que sobra. A diferencia de BulkSaveChanges, no depende de que el ChangeTracker ya tenga marcados los estados.
| Aspecto | SaveChanges() | BulkSaveChanges() | BulkSynchronize() |
|---|---|---|---|
| Fuente de verdad | Entidades cargadas y marcadas en el contexto | Igual que SaveChanges(), pero en lote y optimizado | Lista externa (Excel/CSV/API) que debe reflejarse en la BD |
| Operaciones | Add / Update / Remove por entidad | Add / Update / Remove en operaciones masivas | Insert + Update + Delete en una sola pasada |
| Necesita ChangeTracker | Sí | Sí (lo que ya detectó) | No: compara contra claves definidas (PK o columnas) |
| Escenario ideal | Apps pequeñas / pocos cambios | Aplicar muchos cambios ya cargados en memoria | Integración de datos desde fuentes externas; “poner al día” la tabla |
| Complejidad de código | Baja, pero muchas llamadas | Baja: una sola llamada en lote | Baja: una sola llamada con opciones (claves personalizadas, subconjuntos, etc.) |
Para detalles y opciones adicionales (como claves personalizadas o sincronizar solo un subconjunto), revisa la documentación oficial de BulkSynchronize.
⚙️ ¿Cómo funciona BulkSynchronize en EF Core?
BulkSynchronize en EF Core ejecuta una operación optimizada que combina inserciones, actualizaciones y eliminaciones en una sola transacción. Esta función de Entity Framework Extensions te permite sincronizar datos externos en EF Core sin escribir consultas SQL manuales y con alto rendimiento.
- Definición de claves: identifica cómo reconocer los registros (PK o propiedades que elijas).
- Creación de tabla temporal: tu lista externa se carga rápidamente mediante
BulkInsert(). - Comparación interna: la librería compara tu lista con la tabla de la base de datos.
- Acciones aplicadas:
- Insert para los que no existen.
- Update para los que coinciden.
- Delete para los que ya no están (o soft delete si lo configuras).
- Commit en lote: todo se aplica en una sola operación optimizada, reduciendo viajes al servidor SQL.
⚡ Benchmark oficial • rendimiento de BulkSynchronize
Las pruebas de rendimiento oficial realizadas con SQL Server confirman la eficiencia de BulkSynchronize frente a las operaciones estándar de EF Core. Los resultados fueron obtenidos con BenchmarkDotNet (25 iteraciones, 1 calentamiento) sincronizando 1K, 10K y 100K registros.

Comparativa oficial de ZZZ Projects: tiempo promedio (Mean) y memoria asignada (Allocated) al sincronizar lotes crecientes.
- Los resultados pueden variar según hardware, configuración y tamaño del dataset.
- EF Core no ofrece un BulkSynchronize nativo; la operación mostrada es de Entity Framework Extensions.
🔗 Ver resultados completos y tablas por proveedor: Benchmark — BulkSynchronize (GitHub, ZZZ Projects)
⚙️ Opciones avanzadas
Cuando necesites un control fino de la sincronización, estas opciones de BulkSynchronize te dan mucha flexibilidad:
🪪 Mantener valores de identidad: SynchronizeKeepIdentity
Inserta respetando el valor de la columna identidad (útil en migraciones o importaciones controladas).
// Mantener identidad durante la sincronización
context.BulkSynchronize(clientes, o => o.SynchronizeKeepIdentity = true);
🧩 Sincronizar solo un subconjunto: ColumnSynchronizeDeleteKeySubsetExpression
Limita la sincronización a un subconjunto (por ejemplo, por Tipo, Usuario o Categoría), evitando borrar fuera de ese ámbito.
// Clave compuesta + subconjunto por Tipo
context.BulkSynchronize(items, o =>
{
o.ColumnPrimaryKeyExpression = x => new { x.Codigo, x.Region };
o.ColumnSynchronizeDeleteKeySubsetExpression = x => x.Tipo;
});
🌿 Borrado lógico: SynchronizeSoftDeleteFormula
En vez de eliminar filas ausentes en tu lista, márcalas como inactivas (soft delete) con una fórmula SQL.
// Soft delete en vez de DELETE físico
// Nota: usa la función adecuada a tu proveedor (ej. GETUTCDATE() es de SQL Server).
context.BulkSynchronize(entidades, o =>
{
o.SynchronizeSoftDeleteFormula = "IsDeleted = 1, DeletedAt = GETUTCDATE()";
});
🧱 Ignorar propiedades al insertar/actualizar
Controla qué columnas se insertan o actualizan (fechas de auditoría, cálculos, etc.).
// No actualizar CreatedDate y no insertar UpdatedDate
context.BulkSynchronize(modelos, o =>
{
o.IgnoreOnSynchronizeUpdateExpression = x => x.CreatedDate;
o.IgnoreOnSynchronizeInsertExpression = x => x.UpdatedDate;
});
- Importante: si pasas una lista vacía,
BulkSynchronizeno se ejecuta para evitar eliminar toda la tabla por accidente. - Más opciones y escenarios en la doc oficial de BulkSynchronize.
❓ Preguntas frecuentes (FAQ)
Resolvemos dudas rápidas sobre BulkSynchronize en EF Core:
🗝️ ¿Necesito definir siempre claves?
No necesariamente. Si no defines una clave, se usa la PK de tu modelo por defecto. Puedes personalizarla con ColumnPrimaryKeyExpression o ColumnPrimaryKeyNames cuando lo necesites.
🗑️ ¿Elimina registros automáticamente?
Sí. BulkSynchronize() realiza insert, update y delete de los registros que no estén en la lista externa para dejar la tabla alineada. Si no quieres borrado físico, usa SynchronizeSoftDeleteFormula.
⚡ ¿Hay versión asíncrona?
Sí. Usa BulkSynchronizeAsync(), ideal para aplicaciones Web/API con alto volumen de datos.
🔄 ¿Reemplaza a BulkSaveChanges()?
No. BulkSaveChanges() aplica lo que detectó el ChangeTracker (entidades ya cargadas). BulkSynchronize() compara una lista externa contra la base para insert/update/delete en una sola pasada.
🧾 Checklist de repaso
Antes de cerrar, verifica lo esencial para usar BulkSynchronize en EF Core con Entity Framework Extensions:
- ✅ Instala el paquete
Z.EntityFramework.Extensions.EFCorey agregausing Z.EntityFramework.Extensions;. - ✅ Define (si aplica) una clave de coincidencia personalizada con
ColumnPrimaryKeyExpression/ColumnPrimaryKeyNames. - ✅ Llama a
BulkSynchronize()oBulkSynchronizeAsync()según el escenario. - ✅ Si no quieres borrado físico, configura
SynchronizeSoftDeleteFormula. - ✅ Valida en preproducción/staging antes de aplicar en producción.
🔗 Recursos útiles
Si quieres profundizar más allá de este artículo, aquí tienes referencias oficiales y prácticas:
- 📘 Doc oficial: BulkSynchronize – EF Extensions
- 🌟 Sitio de Entity Framework Extensions: ZZZ Projects
- 📗 EF Core (Microsoft Docs): Documentación oficial
- 🧪 Demo en vivo: .NET Fiddle – BulkSynchronize()
✅ Conclusión
Si tu aplicación necesita integrar datos externos con tu base de datos de forma rápida, consistente y sin lógica repetitiva, BulkSynchronize es la opción más directa. Unifica inserciones, actualizaciones y eliminación en una sola operación optimizada.
👉 ¿Aún no lo tienes? Descarga Entity Framework Extensions e intégralo en tu proyecto.
🎯 ¿Qué sigue?
En los próximos artículos exploraremos UpdateFromQuery y DeleteFromQuery, comparándolos con sus equivalentes nativos ExecuteUpdate y ExecuteDelete de EF Core. Si aún no lo has leído, te recomendamos comenzar por la comparativa técnica entre ExecuteDelete y BatchDelete, donde analizamos rendimiento, compatibilidad y escenarios recomendados para eliminaciones masivas.
⚖️ Nota de legalidad
Este contenido es original y se basa en el uso legítimo de Entity Framework Extensions y Entity Framework Plus. Las marcas y nombres pertenecen a sus respectivos titulares. La información ha sido reinterpretada con fines pedagógicos, incluyendo enlaces a las fuentes oficiales y comparativas de rendimiento.
