Implementato sistema robusto di salvataggio/caricamento profili Data Coupler
- Aggiunto metodo GetCredentialIdByNameAsync in CredentialService per recuperare ID credenziali per nome - Implementata gestione robusta dei profili duplicati con riattivazione, sovrascrittura e auto-rinomina - Migliorata logica di caricamento profili con simulazione workflow utente e logging dettagliato - Fixata gestione errori UNIQUE constraint nel salvataggio profili - Aggiunto supporto per salvataggio ID credenziali reali invece di placeholder - Implementato metodo GetProfileByNameIncludingInactiveAsync per gestire profili inattivi - Aggiunto logging esteso per debug e troubleshooting - Integrato componente ProfileSaver nella UI principale - Risolti errori di compilazione e validazione build completa - Migliorata gestione errori con feedback utente per credenziali/entità mancanti
This commit is contained in:
@@ -39,6 +39,9 @@ public interface ICredentialService
|
||||
Task<bool> DeleteCredentialAsync(int id);
|
||||
Task<bool> DeleteCredentialAsync(string name);
|
||||
Task<List<string>> GetCredentialNamesAsync(CredentialType? type = null);
|
||||
|
||||
// Helper methods to get credential ID by name
|
||||
Task<int?> GetCredentialIdByNameAsync(string name, CredentialType type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -960,5 +963,27 @@ public class CredentialService : ICredentialService
|
||||
credentialValue.Contains("*** ERRORE DECRITTOGRAFIA ***");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene l'ID di una credenziale per nome e tipo
|
||||
/// </summary>
|
||||
/// <param name="name">Nome della credenziale</param>
|
||||
/// <param name="type">Tipo della credenziale</param>
|
||||
/// <returns>ID della credenziale se trovata, null altrimenti</returns>
|
||||
public async Task<int?> GetCredentialIdByNameAsync(string name, CredentialType type)
|
||||
{
|
||||
try
|
||||
{
|
||||
var entity = await _context.Credentials
|
||||
.FirstOrDefaultAsync(c => c.Name == name && c.Type == type.ToString() && c.IsActive);
|
||||
|
||||
return entity?.Id;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Errore nel recuperare l'ID della credenziale: {Name}, Tipo: {Type}", name, type);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -31,6 +31,17 @@ public class DataCouplerProfileService : IDataCouplerProfileService
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene tutti i profili per nome (inclusi quelli inattivi)
|
||||
/// </summary>
|
||||
public async Task<DataCouplerProfile?> GetProfileByNameIncludingInactiveAsync(string name)
|
||||
{
|
||||
return await _context.DataCouplerProfiles
|
||||
.Include(p => p.SourceCredential)
|
||||
.Include(p => p.DestinationCredential)
|
||||
.FirstOrDefaultAsync(p => p.Name.ToLower() == name.ToLower());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene un profilo per ID
|
||||
/// </summary>
|
||||
@@ -80,8 +91,12 @@ public class DataCouplerProfileService : IDataCouplerProfileService
|
||||
throw new InvalidOperationException($"Profilo con ID {profile.Id} non trovato");
|
||||
}
|
||||
|
||||
// Aggiorna le proprietà
|
||||
existingProfile.Name = profile.Name;
|
||||
// Aggiorna le proprietà (evita di aggiornare il nome se è uguale per evitare unique constraint)
|
||||
if (!string.Equals(existingProfile.Name, profile.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
existingProfile.Name = profile.Name;
|
||||
}
|
||||
|
||||
existingProfile.Description = profile.Description;
|
||||
existingProfile.SourceType = profile.SourceType;
|
||||
existingProfile.SourceCredentialId = profile.SourceCredentialId;
|
||||
@@ -94,6 +109,9 @@ public class DataCouplerProfileService : IDataCouplerProfileService
|
||||
existingProfile.DestinationTable = profile.DestinationTable;
|
||||
existingProfile.DestinationEndpoint = profile.DestinationEndpoint;
|
||||
existingProfile.FieldMappingJson = profile.FieldMappingJson;
|
||||
existingProfile.SourceKeyField = profile.SourceKeyField;
|
||||
existingProfile.UseRecordAssociations = profile.UseRecordAssociations;
|
||||
existingProfile.IsActive = profile.IsActive;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return existingProfile;
|
||||
@@ -195,15 +213,19 @@ public class DataCouplerProfileService : IDataCouplerProfileService
|
||||
Description = profile.Description,
|
||||
SourceType = profile.SourceType,
|
||||
SourceCredentialId = profile.SourceCredentialId,
|
||||
SourceCredentialName = profile.SourceCredential?.Name,
|
||||
SourceSchema = profile.SourceSchema,
|
||||
SourceTable = profile.SourceTable,
|
||||
SourceFilePath = profile.SourceFilePath,
|
||||
DestinationType = profile.DestinationType,
|
||||
DestinationCredentialId = profile.DestinationCredentialId,
|
||||
DestinationCredentialName = profile.DestinationCredential?.Name,
|
||||
DestinationSchema = profile.DestinationSchema,
|
||||
DestinationTable = profile.DestinationTable,
|
||||
DestinationEndpoint = profile.DestinationEndpoint,
|
||||
FieldMappings = DeserializeFieldMappings(profile.FieldMappingJson)
|
||||
FieldMappings = DeserializeFieldMappings(profile.FieldMappingJson),
|
||||
SourceKeyField = profile.SourceKeyField,
|
||||
UseRecordAssociations = profile.UseRecordAssociations
|
||||
};
|
||||
}
|
||||
|
||||
@@ -228,6 +250,8 @@ public class DataCouplerProfileService : IDataCouplerProfileService
|
||||
DestinationTable = dto.DestinationTable,
|
||||
DestinationEndpoint = dto.DestinationEndpoint,
|
||||
FieldMappingJson = SerializeFieldMappings(dto.FieldMappings),
|
||||
SourceKeyField = dto.SourceKeyField,
|
||||
UseRecordAssociations = dto.UseRecordAssociations,
|
||||
CreatedBy = createdBy
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ public interface IDataCouplerProfileService
|
||||
/// </summary>
|
||||
Task<IEnumerable<DataCouplerProfile>> GetAllProfilesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene tutti i profili per nome (inclusi quelli inattivi)
|
||||
/// </summary>
|
||||
Task<DataCouplerProfile?> GetProfileByNameIncludingInactiveAsync(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene un profilo per ID
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user