diff --git a/Elecciones-Web/src/Elecciones.Worker/CriticalDataWorker.cs b/Elecciones-Web/src/Elecciones.Worker/CriticalDataWorker.cs index 36e02b8..fc3e66b 100644 --- a/Elecciones-Web/src/Elecciones.Worker/CriticalDataWorker.cs +++ b/Elecciones-Web/src/Elecciones.Worker/CriticalDataWorker.cs @@ -109,45 +109,35 @@ public class CriticalDataWorker : BackgroundService .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) .ToListAsync(stoppingToken); - // --- MODIFICACIÓN 1: Obtener todos los ámbitos en una sola consulta --- var ambitosASondear = await dbContext.AmbitosGeograficos .AsNoTracking() - .Where(a => (a.NivelId == 10 || a.NivelId == 20) && a.DistritoId != null) + .Where(a => a.NivelId == 10 && a.DistritoId != null) .ToListAsync(stoppingToken); - var provincia = ambitosASondear.FirstOrDefault(a => a.NivelId == 10); - var seccionesElectorales = ambitosASondear.Where(a => a.NivelId == 20).ToList(); - - if (!categoriasDeBancas.Any() || provincia == null) + if (!categoriasDeBancas.Any() || !ambitosASondear.Any()) { - _logger.LogWarning("No se encontraron categorías de bancas o el ámbito provincial en la BD. Omitiendo sondeo de bancas."); + _logger.LogWarning("No se encontraron categorías de bancas o ámbitos provinciales en la BD. Omitiendo sondeo de bancas."); return; } - _logger.LogInformation("Iniciando sondeo de Bancas a nivel Provincial y para {count} Secciones Electorales...", seccionesElectorales.Count); + _logger.LogInformation("Iniciando sondeo de Bancas a nivel Provincial para {count} provincias...", ambitosASondear.Count); var todasLasProyecciones = new List(); bool hasReceivedAnyNewData = false; - - // --- MODIFICACIÓN 2: Usar un diccionario para no buscar repetidamente en la BD --- var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken); - // Bucle combinado para todos los ámbitos foreach (var ambito in ambitosASondear) { if (stoppingToken.IsCancellationRequested) break; - foreach (var categoria in categoriasDeBancas) { if (stoppingToken.IsCancellationRequested) break; - // Llamada a la API (lógica adaptada para ambos niveles) var repartoBancasDto = await _apiService.GetBancasAsync(authToken, ambito.DistritoId!, ambito.SeccionProvincialId, categoria.Id); if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) { hasReceivedAnyNewData = true; - DateTime fechaTotalizacion; if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) { @@ -161,20 +151,17 @@ public class CriticalDataWorker : BackgroundService foreach (var banca in bancas) { - // --- MODIFICACIÓN 3: Lógica de "Upsert" para Agrupaciones --- if (!agrupacionesEnDb.ContainsKey(banca.IdAgrupacion)) { _logger.LogWarning("Agrupación con ID {AgrupacionId} ('{Nombre}') no encontrada. Creándola desde los datos de bancas.", banca.IdAgrupacion, banca.NombreAgrupacion); - var nuevaAgrupacion = new AgrupacionPolitica { Id = banca.IdAgrupacion, Nombre = banca.NombreAgrupacion, IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty }; - await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); - agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); // Añadir al diccionario para no volver a crearla + agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); } todasLasProyecciones.Add(new ProyeccionBanca @@ -195,16 +182,11 @@ public class CriticalDataWorker : BackgroundService { _logger.LogInformation("Se recibieron datos válidos de bancas. Procediendo a actualizar la base de datos..."); await using var transaction = await dbContext.Database.BeginTransactionAsync(stoppingToken); - - // Si se crearon nuevas agrupaciones, se guardarán aquí primero. - await dbContext.SaveChangesAsync(stoppingToken); - - // Luego, procedemos con las proyecciones. - await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); + await dbContext.SaveChangesAsync(stoppingToken); // Guardar nuevas agrupaciones si las hay + await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas WHERE EleccionId = {0}", EleccionId, stoppingToken); // CORRECCIÓN: Borrar solo para la elección actual await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); await dbContext.SaveChangesAsync(stoppingToken); await transaction.CommitAsync(stoppingToken); - _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); } else diff --git a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs index a375e5e..27ce044 100644 --- a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs +++ b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs @@ -572,45 +572,35 @@ public class LowPriorityDataWorker : BackgroundService .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) .ToListAsync(stoppingToken); - // --- MODIFICACIÓN 1: Obtener todos los ámbitos en una sola consulta --- var ambitosASondear = await dbContext.AmbitosGeograficos .AsNoTracking() - .Where(a => (a.NivelId == 10 || a.NivelId == 20) && a.DistritoId != null) + .Where(a => a.NivelId == 10 && a.DistritoId != null) .ToListAsync(stoppingToken); - var provincia = ambitosASondear.FirstOrDefault(a => a.NivelId == 10); - var seccionesElectorales = ambitosASondear.Where(a => a.NivelId == 20).ToList(); - - if (!categoriasDeBancas.Any() || provincia == null) + if (!categoriasDeBancas.Any() || !ambitosASondear.Any()) { - _logger.LogWarning("No se encontraron categorías de bancas o el ámbito provincial en la BD. Omitiendo sondeo de bancas."); + _logger.LogWarning("No se encontraron categorías de bancas o ámbitos provinciales en la BD. Omitiendo sondeo de bancas."); return; } - _logger.LogInformation("Iniciando sondeo de Bancas a nivel Provincial y para {count} Secciones Electorales...", seccionesElectorales.Count); + _logger.LogInformation("Iniciando sondeo de Bancas a nivel Provincial para {count} provincias...", ambitosASondear.Count); var todasLasProyecciones = new List(); bool hasReceivedAnyNewData = false; - - // --- MODIFICACIÓN 2: Usar un diccionario para no buscar repetidamente en la BD --- var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken); - // Bucle combinado para todos los ámbitos foreach (var ambito in ambitosASondear) { if (stoppingToken.IsCancellationRequested) break; - foreach (var categoria in categoriasDeBancas) { if (stoppingToken.IsCancellationRequested) break; - // Llamada a la API (lógica adaptada para ambos niveles) var repartoBancasDto = await _apiService.GetBancasAsync(authToken, ambito.DistritoId!, ambito.SeccionProvincialId, categoria.Id); if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) { hasReceivedAnyNewData = true; - DateTime fechaTotalizacion; if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) { @@ -624,20 +614,17 @@ public class LowPriorityDataWorker : BackgroundService foreach (var banca in bancas) { - // --- MODIFICACIÓN 3: Lógica de "Upsert" para Agrupaciones --- if (!agrupacionesEnDb.ContainsKey(banca.IdAgrupacion)) { _logger.LogWarning("Agrupación con ID {AgrupacionId} ('{Nombre}') no encontrada. Creándola desde los datos de bancas.", banca.IdAgrupacion, banca.NombreAgrupacion); - var nuevaAgrupacion = new AgrupacionPolitica { Id = banca.IdAgrupacion, Nombre = banca.NombreAgrupacion, IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty }; - await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); - agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); // Añadir al diccionario para no volver a crearla + agrupacionesEnDb.Add(nuevaAgrupacion.Id, nuevaAgrupacion); } todasLasProyecciones.Add(new ProyeccionBanca @@ -658,16 +645,11 @@ public class LowPriorityDataWorker : BackgroundService { _logger.LogInformation("Se recibieron datos válidos de bancas. Procediendo a actualizar la base de datos..."); await using var transaction = await dbContext.Database.BeginTransactionAsync(stoppingToken); - - // Si se crearon nuevas agrupaciones, se guardarán aquí primero. - await dbContext.SaveChangesAsync(stoppingToken); - - // Luego, procedemos con las proyecciones. - await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); + await dbContext.SaveChangesAsync(stoppingToken); // Guardar nuevas agrupaciones si las hay + await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas WHERE EleccionId = {0}", EleccionId, stoppingToken); // CORRECCIÓN: Borrar solo para la elección actual await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); await dbContext.SaveChangesAsync(stoppingToken); await transaction.CommitAsync(stoppingToken); - _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); } else