Corregge il problema di inizializzazione database per la tabella DataCouplerProfiles

- Sostituito EnsureCreatedAsync con MigrateAsync nel DatabaseInitializer
- Aggiunta gestione automatica delle migrazioni pendenti al startup
- Migliorata verifica delle tabelle includendo DataCouplerProfiles
- Rimossa logica obsoleta di ApplyMigrationsAsync
- Risolto errore "no such table: DataCouplerProfiles" nel salvataggio profili

Questo fix garantisce che tutte le migrazioni vengano applicate correttamente,
permettendo il corretto funzionamento del sistema di salvataggio
This commit is contained in:
Alessio Dal Santo
2025-07-02 16:32:31 +02:00
parent 373eae0a5a
commit d837339f7e
4 changed files with 44 additions and 124 deletions
+44 -124
View File
@@ -31,13 +31,17 @@ public class DatabaseInitializer : IDatabaseInitializer
{
_logger.LogInformation("Inizializzazione database in corso...");
// Per SQLite con EnsureCreatedAsync è più semplice e sicuro
// Crea il database e le tabelle se non esistono
var created = await _context.Database.EnsureCreatedAsync();
// Verifica se il database esiste
var databaseExists = await _context.Database.CanConnectAsync();
if (created)
if (!databaseExists)
{
_logger.LogInformation("Database creato con successo");
_logger.LogInformation("Database non esistente, creazione in corso...");
// Applica tutte le migrazioni per creare il database con la struttura più recente
await _context.Database.MigrateAsync();
_logger.LogInformation("Database creato con tutte le migrazioni applicate");
// Aggiungi dati di esempio se necessario
await SeedInitialDataAsync();
@@ -46,11 +50,23 @@ public class DatabaseInitializer : IDatabaseInitializer
{
_logger.LogInformation("Database esistente trovato");
// Applica eventuali migrazioni pendenti
var pendingMigrations = await _context.Database.GetPendingMigrationsAsync();
if (pendingMigrations.Any())
{
_logger.LogInformation("Trovate {Count} migrazioni pendenti: {Migrations}",
pendingMigrations.Count(), string.Join(", ", pendingMigrations));
await _context.Database.MigrateAsync();
_logger.LogInformation("Migrazioni applicate con successo");
}
else
{
_logger.LogInformation("Nessuna migrazione pendente");
}
// Verifica che le tabelle esistano
await VerifyTablesAsync();
// Applica migrazioni se necessario
await ApplyMigrationsAsync();
}
}
catch (Exception ex)
@@ -68,28 +84,35 @@ public class DatabaseInitializer : IDatabaseInitializer
await _context.Credentials.CountAsync();
_logger.LogInformation("Tabella Credentials verificata con successo");
// Verifica se la tabella KeyAssociations esiste, se non esiste la crea senza ricreare tutto il database
// Verifica se la tabella KeyAssociations esiste
try
{
await _context.KeyAssociations.CountAsync();
_logger.LogInformation("Tabella KeyAssociations verificata con successo");
}
catch (Exception)
catch (Exception ex)
{
_logger.LogInformation("Tabella KeyAssociations non trovata, creazione tramite migrazione...");
await CreateKeyAssociationsTableAsync();
_logger.LogWarning(ex, "Tabella KeyAssociations non accessibile");
}
// Verifica se la tabella DataCouplerProfiles esiste
try
{
await _context.DataCouplerProfiles.CountAsync();
_logger.LogInformation("Tabella DataCouplerProfiles verificata con successo");
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Tabella DataCouplerProfiles non accessibile");
}
}
catch (Exception)
catch (Exception ex)
{
_logger.LogWarning("Tabella Credentials mancante, ricreazione database...");
_logger.LogError(ex, "Errore nella verifica delle tabelle");
// Solo se la tabella principale non esiste, ricreiamo tutto
await _context.Database.EnsureDeletedAsync();
await _context.Database.EnsureCreatedAsync();
await SeedInitialDataAsync();
_logger.LogInformation("Database ricreato con successo");
// Se ci sono problemi gravi, prova a riapplicare le migrazioni
_logger.LogInformation("Tentativo di riapplicazione delle migrazioni...");
await _context.Database.MigrateAsync();
}
}
@@ -148,110 +171,7 @@ public class DatabaseInitializer : IDatabaseInitializer
_logger.LogError(ex, "Errore durante il seeding dei dati iniziali");
throw;
}
} private async Task ApplyMigrationsAsync()
{
try
{
_logger.LogInformation("Verifica e applicazione migrazioni...");
// Migrazione 1: Verifica se la colonna RestServiceType esiste
try
{
await _context.Database.ExecuteSqlRawAsync(
"SELECT RestServiceType FROM Credentials LIMIT 1");
_logger.LogInformation("Colonna RestServiceType già presente");
}
catch (Microsoft.Data.Sqlite.SqliteException)
{
// La colonna non esiste, la aggiungiamo
_logger.LogInformation("Aggiunta colonna RestServiceType...");
await _context.Database.ExecuteSqlRawAsync(
"ALTER TABLE Credentials ADD COLUMN RestServiceType TEXT");
_logger.LogInformation("Colonna RestServiceType aggiunta con successo");
}
// Migrazione 2: Elimina vecchia tabella RecordAssociations se esiste e crea KeyAssociations
try
{
// Prova a eliminare la vecchia tabella se esiste
await _context.Database.ExecuteSqlRawAsync("DROP TABLE IF EXISTS RecordAssociations");
_logger.LogInformation("Vecchia tabella RecordAssociations eliminata");
}
catch (Exception)
{
// Ignora errori se la tabella non esiste
}
// Verifica se la tabella KeyAssociations esiste
try
{
await _context.Database.ExecuteSqlRawAsync(
"SELECT COUNT(*) FROM KeyAssociations LIMIT 1");
_logger.LogInformation("Tabella KeyAssociations già presente");
}
catch (Microsoft.Data.Sqlite.SqliteException)
{
// La tabella non esiste, la creiamo
_logger.LogInformation("Creazione tabella KeyAssociations...");
// Crea la tabella
await _context.Database.ExecuteSqlRawAsync(@"
CREATE TABLE KeyAssociations (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
KeyValue TEXT NOT NULL,
SourceKeyField TEXT NOT NULL,
DestinationKeyField TEXT NOT NULL,
DestinationEntity TEXT NOT NULL,
DestinationId TEXT NOT NULL,
RestCredentialName TEXT NOT NULL,
CreatedAt TEXT NOT NULL DEFAULT (datetime('now')),
UpdatedAt TEXT,
LastVerifiedAt TEXT,
IsActive INTEGER NOT NULL DEFAULT 1,
SourcesInfo TEXT,
AdditionalInfo TEXT
)");
// Crea gli indici
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_KeyValue
ON KeyAssociations (KeyValue)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE UNIQUE INDEX IX_KeyAssociations_Unique
ON KeyAssociations (KeyValue, DestinationEntity, RestCredentialName)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_DestinationEntity
ON KeyAssociations (DestinationEntity)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_RestCredentialName
ON KeyAssociations (RestCredentialName)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_IsActive
ON KeyAssociations (IsActive)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_CreatedAt
ON KeyAssociations (CreatedAt)");
await _context.Database.ExecuteSqlRawAsync(@"
CREATE INDEX IX_KeyAssociations_LastVerifiedAt
ON KeyAssociations (LastVerifiedAt)");
_logger.LogInformation("Tabella KeyAssociations creata con successo");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore nell'applicazione delle migrazioni");
throw;
}
}
private async Task CreateKeyAssociationsTableAsync()
} private async Task CreateKeyAssociationsTableAsync()
{
try
{
Binary file not shown.
Binary file not shown.
Binary file not shown.