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:
@@ -31,13 +31,17 @@ public class DatabaseInitializer : IDatabaseInitializer
|
|||||||
{
|
{
|
||||||
_logger.LogInformation("Inizializzazione database in corso...");
|
_logger.LogInformation("Inizializzazione database in corso...");
|
||||||
|
|
||||||
// Per SQLite con EnsureCreatedAsync è più semplice e sicuro
|
// Verifica se il database esiste
|
||||||
// Crea il database e le tabelle se non esistono
|
var databaseExists = await _context.Database.CanConnectAsync();
|
||||||
var created = await _context.Database.EnsureCreatedAsync();
|
|
||||||
|
|
||||||
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
|
// Aggiungi dati di esempio se necessario
|
||||||
await SeedInitialDataAsync();
|
await SeedInitialDataAsync();
|
||||||
@@ -46,11 +50,23 @@ public class DatabaseInitializer : IDatabaseInitializer
|
|||||||
{
|
{
|
||||||
_logger.LogInformation("Database esistente trovato");
|
_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
|
// Verifica che le tabelle esistano
|
||||||
await VerifyTablesAsync();
|
await VerifyTablesAsync();
|
||||||
|
|
||||||
// Applica migrazioni se necessario
|
|
||||||
await ApplyMigrationsAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -68,28 +84,35 @@ public class DatabaseInitializer : IDatabaseInitializer
|
|||||||
await _context.Credentials.CountAsync();
|
await _context.Credentials.CountAsync();
|
||||||
_logger.LogInformation("Tabella Credentials verificata con successo");
|
_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
|
try
|
||||||
{
|
{
|
||||||
await _context.KeyAssociations.CountAsync();
|
await _context.KeyAssociations.CountAsync();
|
||||||
_logger.LogInformation("Tabella KeyAssociations verificata con successo");
|
_logger.LogInformation("Tabella KeyAssociations verificata con successo");
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Tabella KeyAssociations non trovata, creazione tramite migrazione...");
|
_logger.LogWarning(ex, "Tabella KeyAssociations non accessibile");
|
||||||
await CreateKeyAssociationsTableAsync();
|
}
|
||||||
|
|
||||||
|
// 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
|
// Se ci sono problemi gravi, prova a riapplicare le migrazioni
|
||||||
await _context.Database.EnsureDeletedAsync();
|
_logger.LogInformation("Tentativo di riapplicazione delle migrazioni...");
|
||||||
await _context.Database.EnsureCreatedAsync();
|
await _context.Database.MigrateAsync();
|
||||||
await SeedInitialDataAsync();
|
|
||||||
|
|
||||||
_logger.LogInformation("Database ricreato con successo");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,110 +171,7 @@ public class DatabaseInitializer : IDatabaseInitializer
|
|||||||
_logger.LogError(ex, "Errore durante il seeding dei dati iniziali");
|
_logger.LogError(ex, "Errore durante il seeding dei dati iniziali");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
} private async Task ApplyMigrationsAsync()
|
} private async Task CreateKeyAssociationsTableAsync()
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user