Files
Data-Coupler/DataConnection/DB/EF/DbManagerOptions.cs
Alessio Dal Santo 01f78466df [Feature] Implementazione completa supporto ODBC
- Aggiunta persistenza campi ODBC (OdbcDsnName, OdbcMode) in CredentialEntity
- Creata migration EF Core per nuovi campi database
- Aggiornato mapping credenziali per caricare/salvare dati ODBC
- Creato OdbcDatabaseManager dedicato (bypass EF Core che non supporta ODBC)
- Aggiornato DataConnectionFactory per usare OdbcDatabaseManager con connessioni ODBC
- Fix auto-load DSN: sostituito @onchange con @bind-Value:after in dropdown tipo database
- Fix test connessione SAP HANA: rimossa query SELECT 1 che causava errori sintassi
- Implementati tutti i metodi IDatabaseManager in OdbcDatabaseManager
- Supporto completo per discovery schema, tabelle e query ODBC

Risolve problema DbContext non configurato per ODBC e abilita connessioni ODBC complete.
2026-02-02 18:24:44 +01:00

133 lines
4.7 KiB
C#

using System;
using Microsoft.EntityFrameworkCore;
using DataConnection.Interfaces;
using DataConnection.EF.DatabaseDiscovery;
using DataConnection.Enums;
namespace DataConnection.EF;
/// <summary>
/// Opzioni per la configurazione del manager di database esistenti
/// </summary>
public class DbManagerOptions
{
/// <summary>
/// Configuratore del DbContext
/// </summary>
public Action<DbContextOptionsBuilder> DbContextConfigurator { get; set; }
/// <summary>
/// Configuratore del modello del database
/// </summary>
public Action<ModelBuilder> ModelConfigurator { get; set; }
/// <summary>
/// Flag che indica se la scoperta automatica delle entità è abilitata
/// </summary>
public bool EnableAutoDiscovery { get; set; }
/// <summary>
/// Assembly da cui caricare automaticamente le entità (se EnableAutoDiscovery = true)
/// </summary>
public System.Reflection.Assembly EntityAssembly { get; set; }
/// <summary>
/// Namespace in cui cercare le entità (se EnableAutoDiscovery = true)
/// </summary>
public string EntityNamespace { get; set; }
/// <summary>
/// Timeout per le operazioni del database (in secondi)
/// </summary>
public int CommandTimeout { get; set; } = 30;
/// <summary>
/// Strategia di mappatura dei nomi (CamelCase, PascalCase, SnakeCase)
/// </summary>
public NamingStrategy NamingStrategy { get; set; } = NamingStrategy.Default;
/// <summary>
/// Servizio per la scoperta dei database disponibili sul server
/// </summary>
public IDatabaseDiscovery DatabaseDiscoveryService { get; set; }
/// <summary>
/// Stringa di connessione a livello di server (senza specificare il database)
/// </summary>
public string ServerConnectionString { get; set; }
/// <summary>
/// Nome del database a cui connettersi
/// </summary>
public string DatabaseName { get; set; }
/// <summary>
/// Tipo di database (SqlServer, MySql, ecc.)
/// </summary>
public DatabaseType DatabaseType { get; set; } = DatabaseType.SqlServer; /// <summary>
/// Configura automaticamente il servizio di scoperta database in base al tipo di database
/// </summary>
/// <param name="databaseType">Tipo di database</param>
public void ConfigureDatabaseDiscovery(DatabaseType databaseType)
{
DatabaseType = databaseType;
switch (databaseType)
{
case DatabaseType.SqlServer:
DatabaseDiscoveryService = new SqlServerDatabaseDiscovery();
DbContextConfigurator = options => options.UseSqlServer(BuildFullConnectionString(),
sqlOptions => sqlOptions.CommandTimeout(CommandTimeout));
break;
case DatabaseType.Odbc:
// Per ODBC non c'è un provider EF Core specifico, useremo connessioni dirette
// Il DatabaseDiscoveryService può essere null per ODBC
DatabaseDiscoveryService = null!;
DbContextConfigurator = options =>
{
// ODBC non ha un provider EF Core nativo, quindi configuriamo un provider generico
// Le query verranno eseguite tramite connessioni dirette ADO.NET
};
break;
default:
// Per altri database, configuriamo un configuratore di base che non fa nulla
// Il test di connessione userà un approccio diverso
DbContextConfigurator = options => { };
break;
}
}
/// <summary>
/// Costruisce una stringa di connessione completa includendo il database selezionato
/// </summary>
public string BuildFullConnectionString()
{
if (string.IsNullOrEmpty(ServerConnectionString))
{
throw new InvalidOperationException("La stringa di connessione al server non è stata specificata");
}
if (string.IsNullOrEmpty(DatabaseName))
{
return ServerConnectionString;
}
// Per SQL Server
if (ServerConnectionString.Contains("Initial Catalog=") || ServerConnectionString.Contains("Database="))
{
// Sostituisci il database esistente
var modifiedString = System.Text.RegularExpressions.Regex.Replace(
ServerConnectionString,
@"(Initial Catalog|Database)=([^;]*)",
$"$1={DatabaseName}");
return modifiedString;
}
else
{
// Aggiungi il database
return ServerConnectionString + $";Database={DatabaseName}";
}
}
}