Fix Consulta de Bancas
- Se elimina la iteración sobre las secciones para la consulta de bancas.
This commit is contained in:
		| @@ -109,45 +109,35 @@ public class CriticalDataWorker : BackgroundService | |||||||
|           .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) |           .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) | ||||||
|           .ToListAsync(stoppingToken); |           .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|       // --- MODIFICACIÓN 1: Obtener todos los ámbitos en una sola consulta --- |  | ||||||
|       var ambitosASondear = await dbContext.AmbitosGeograficos |       var ambitosASondear = await dbContext.AmbitosGeograficos | ||||||
|           .AsNoTracking() |           .AsNoTracking() | ||||||
|           .Where(a => (a.NivelId == 10 || a.NivelId == 20) && a.DistritoId != null) |           .Where(a => a.NivelId == 10 && a.DistritoId != null) | ||||||
|           .ToListAsync(stoppingToken); |           .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|       var provincia = ambitosASondear.FirstOrDefault(a => a.NivelId == 10); |       if (!categoriasDeBancas.Any() || !ambitosASondear.Any()) | ||||||
|       var seccionesElectorales = ambitosASondear.Where(a => a.NivelId == 20).ToList(); |  | ||||||
|  |  | ||||||
|       if (!categoriasDeBancas.Any() || provincia == null) |  | ||||||
|       { |       { | ||||||
|         _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; |         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<ProyeccionBanca>(); |       var todasLasProyecciones = new List<ProyeccionBanca>(); | ||||||
|       bool hasReceivedAnyNewData = false; |       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); |       var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken); | ||||||
|  |  | ||||||
|       // Bucle combinado para todos los ámbitos |  | ||||||
|       foreach (var ambito in ambitosASondear) |       foreach (var ambito in ambitosASondear) | ||||||
|       { |       { | ||||||
|         if (stoppingToken.IsCancellationRequested) break; |         if (stoppingToken.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|         foreach (var categoria in categoriasDeBancas) |         foreach (var categoria in categoriasDeBancas) | ||||||
|         { |         { | ||||||
|           if (stoppingToken.IsCancellationRequested) break; |           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); |           var repartoBancasDto = await _apiService.GetBancasAsync(authToken, ambito.DistritoId!, ambito.SeccionProvincialId, categoria.Id); | ||||||
|  |  | ||||||
|           if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) |           if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) | ||||||
|           { |           { | ||||||
|             hasReceivedAnyNewData = true; |             hasReceivedAnyNewData = true; | ||||||
|  |  | ||||||
|             DateTime fechaTotalizacion; |             DateTime fechaTotalizacion; | ||||||
|             if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) |             if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) | ||||||
|             { |             { | ||||||
| @@ -161,20 +151,17 @@ public class CriticalDataWorker : BackgroundService | |||||||
|  |  | ||||||
|             foreach (var banca in bancas) |             foreach (var banca in bancas) | ||||||
|             { |             { | ||||||
|               // --- MODIFICACIÓN 3: Lógica de "Upsert" para Agrupaciones --- |  | ||||||
|               if (!agrupacionesEnDb.ContainsKey(banca.IdAgrupacion)) |               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); |                 _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 |                 var nuevaAgrupacion = new AgrupacionPolitica | ||||||
|                 { |                 { | ||||||
|                   Id = banca.IdAgrupacion, |                   Id = banca.IdAgrupacion, | ||||||
|                   Nombre = banca.NombreAgrupacion, |                   Nombre = banca.NombreAgrupacion, | ||||||
|                   IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty |                   IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty | ||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|                 await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); |                 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 |               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..."); |         _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); |         await using var transaction = await dbContext.Database.BeginTransactionAsync(stoppingToken); | ||||||
|  |         await dbContext.SaveChangesAsync(stoppingToken); // Guardar nuevas agrupaciones si las hay | ||||||
|         // Si se crearon nuevas agrupaciones, se guardarán aquí primero. |         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas WHERE EleccionId = {0}", EleccionId, stoppingToken); // CORRECCIÓN: Borrar solo para la elección actual | ||||||
|         await dbContext.SaveChangesAsync(stoppingToken); |  | ||||||
|  |  | ||||||
|         // Luego, procedemos con las proyecciones. |  | ||||||
|         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); |  | ||||||
|         await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); |         await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); | ||||||
|         await dbContext.SaveChangesAsync(stoppingToken); |         await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|         await transaction.CommitAsync(stoppingToken); |         await transaction.CommitAsync(stoppingToken); | ||||||
|  |  | ||||||
|         _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); |         _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|   | |||||||
| @@ -572,45 +572,35 @@ public class LowPriorityDataWorker : BackgroundService | |||||||
|           .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) |           .Where(c => c.Nombre.Contains("SENADORES") || c.Nombre.Contains("DIPUTADOS")) | ||||||
|           .ToListAsync(stoppingToken); |           .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|       // --- MODIFICACIÓN 1: Obtener todos los ámbitos en una sola consulta --- |  | ||||||
|       var ambitosASondear = await dbContext.AmbitosGeograficos |       var ambitosASondear = await dbContext.AmbitosGeograficos | ||||||
|           .AsNoTracking() |           .AsNoTracking() | ||||||
|           .Where(a => (a.NivelId == 10 || a.NivelId == 20) && a.DistritoId != null) |           .Where(a => a.NivelId == 10 && a.DistritoId != null) | ||||||
|           .ToListAsync(stoppingToken); |           .ToListAsync(stoppingToken); | ||||||
|  |  | ||||||
|       var provincia = ambitosASondear.FirstOrDefault(a => a.NivelId == 10); |       if (!categoriasDeBancas.Any() || !ambitosASondear.Any()) | ||||||
|       var seccionesElectorales = ambitosASondear.Where(a => a.NivelId == 20).ToList(); |  | ||||||
|  |  | ||||||
|       if (!categoriasDeBancas.Any() || provincia == null) |  | ||||||
|       { |       { | ||||||
|         _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; |         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<ProyeccionBanca>(); |       var todasLasProyecciones = new List<ProyeccionBanca>(); | ||||||
|       bool hasReceivedAnyNewData = false; |       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); |       var agrupacionesEnDb = await dbContext.AgrupacionesPoliticas.ToDictionaryAsync(a => a.Id, a => a, stoppingToken); | ||||||
|  |  | ||||||
|       // Bucle combinado para todos los ámbitos |  | ||||||
|       foreach (var ambito in ambitosASondear) |       foreach (var ambito in ambitosASondear) | ||||||
|       { |       { | ||||||
|         if (stoppingToken.IsCancellationRequested) break; |         if (stoppingToken.IsCancellationRequested) break; | ||||||
|  |  | ||||||
|         foreach (var categoria in categoriasDeBancas) |         foreach (var categoria in categoriasDeBancas) | ||||||
|         { |         { | ||||||
|           if (stoppingToken.IsCancellationRequested) break; |           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); |           var repartoBancasDto = await _apiService.GetBancasAsync(authToken, ambito.DistritoId!, ambito.SeccionProvincialId, categoria.Id); | ||||||
|  |  | ||||||
|           if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) |           if (repartoBancasDto?.RepartoBancas is { Count: > 0 } bancas) | ||||||
|           { |           { | ||||||
|             hasReceivedAnyNewData = true; |             hasReceivedAnyNewData = true; | ||||||
|  |  | ||||||
|             DateTime fechaTotalizacion; |             DateTime fechaTotalizacion; | ||||||
|             if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) |             if (!DateTime.TryParse(repartoBancasDto.FechaTotalizacion, out var parsedDate)) | ||||||
|             { |             { | ||||||
| @@ -624,20 +614,17 @@ public class LowPriorityDataWorker : BackgroundService | |||||||
|  |  | ||||||
|             foreach (var banca in bancas) |             foreach (var banca in bancas) | ||||||
|             { |             { | ||||||
|               // --- MODIFICACIÓN 3: Lógica de "Upsert" para Agrupaciones --- |  | ||||||
|               if (!agrupacionesEnDb.ContainsKey(banca.IdAgrupacion)) |               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); |                 _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 |                 var nuevaAgrupacion = new AgrupacionPolitica | ||||||
|                 { |                 { | ||||||
|                   Id = banca.IdAgrupacion, |                   Id = banca.IdAgrupacion, | ||||||
|                   Nombre = banca.NombreAgrupacion, |                   Nombre = banca.NombreAgrupacion, | ||||||
|                   IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty |                   IdTelegrama = banca.IdAgrupacionTelegrama ?? string.Empty | ||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|                 await dbContext.AgrupacionesPoliticas.AddAsync(nuevaAgrupacion, stoppingToken); |                 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 |               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..."); |         _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); |         await using var transaction = await dbContext.Database.BeginTransactionAsync(stoppingToken); | ||||||
|  |         await dbContext.SaveChangesAsync(stoppingToken); // Guardar nuevas agrupaciones si las hay | ||||||
|         // Si se crearon nuevas agrupaciones, se guardarán aquí primero. |         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas WHERE EleccionId = {0}", EleccionId, stoppingToken); // CORRECCIÓN: Borrar solo para la elección actual | ||||||
|         await dbContext.SaveChangesAsync(stoppingToken); |  | ||||||
|  |  | ||||||
|         // Luego, procedemos con las proyecciones. |  | ||||||
|         await dbContext.Database.ExecuteSqlRawAsync("DELETE FROM ProyeccionesBancas", stoppingToken); |  | ||||||
|         await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); |         await dbContext.ProyeccionesBancas.AddRangeAsync(todasLasProyecciones, stoppingToken); | ||||||
|         await dbContext.SaveChangesAsync(stoppingToken); |         await dbContext.SaveChangesAsync(stoppingToken); | ||||||
|         await transaction.CommitAsync(stoppingToken); |         await transaction.CommitAsync(stoppingToken); | ||||||
|  |  | ||||||
|         _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); |         _logger.LogInformation("La tabla de proyecciones ha sido actualizada con {count} registros.", todasLasProyecciones.Count); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user