feat: Implement ExistingDatabaseContext for managing existing databases with customizable naming strategies and auto-discovery of entities
feat: Add SqlServerSchemaProvider for extracting database schema information from SQL Server feat: Introduce DatabaseType and NamingStrategy enums for better database management and naming conventions feat: Create IDatabaseDiscovery and IDatabaseManager interfaces for database operations and metadata retrieval feat: Develop REST service client architecture with BaseRestServiceClient and SAP Business One specific implementation feat: Implement REST service discovery page with UI for connecting to SAP Business One Service Layer and displaying discovered entities
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using DataConnection.Enums;
|
||||
|
||||
namespace DataConnection.EF;
|
||||
|
||||
/// <summary>
|
||||
/// DbContext per gestione database esistenti
|
||||
/// </summary>
|
||||
public class ExistingDatabaseContext : DbContext
|
||||
{
|
||||
private readonly Action<ModelBuilder> _modelConfigurator;
|
||||
private readonly bool _enableAutoDiscovery;
|
||||
private readonly Assembly _entityAssembly;
|
||||
private readonly string _entityNamespace;
|
||||
private readonly NamingStrategy _namingStrategy;
|
||||
|
||||
public ExistingDatabaseContext(
|
||||
DbContextOptions options,
|
||||
Action<ModelBuilder> modelConfigurator = null,
|
||||
bool enableAutoDiscovery = false,
|
||||
Assembly entityAssembly = null,
|
||||
string entityNamespace = null,
|
||||
NamingStrategy namingStrategy = NamingStrategy.Default)
|
||||
: base(options)
|
||||
{
|
||||
_modelConfigurator = modelConfigurator;
|
||||
_enableAutoDiscovery = enableAutoDiscovery;
|
||||
_entityAssembly = entityAssembly;
|
||||
_entityNamespace = entityNamespace;
|
||||
_namingStrategy = namingStrategy;
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Applica la strategia di mappatura dei nomi
|
||||
ApplyNamingStrategy(modelBuilder);
|
||||
|
||||
// Applica la configurazione personalizzata se fornita
|
||||
_modelConfigurator?.Invoke(modelBuilder);
|
||||
|
||||
// Scoperta automatica delle entità
|
||||
if (_enableAutoDiscovery && _entityAssembly != null)
|
||||
{
|
||||
DiscoverEntities(modelBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyNamingStrategy(ModelBuilder modelBuilder)
|
||||
{
|
||||
switch (_namingStrategy)
|
||||
{
|
||||
case NamingStrategy.CamelCase:
|
||||
foreach (var entity in modelBuilder.Model.GetEntityTypes())
|
||||
{
|
||||
// Converti il nome della tabella in camelCase
|
||||
string tableName = entity.GetTableName();
|
||||
if (!string.IsNullOrEmpty(tableName) && char.IsUpper(tableName[0]))
|
||||
entity.SetTableName(char.ToLower(tableName[0]) + tableName.Substring(1));
|
||||
|
||||
// Converti i nomi delle proprietà in camelCase
|
||||
foreach (var property in entity.GetProperties())
|
||||
{
|
||||
string propertyName = property.GetColumnName();
|
||||
if (!string.IsNullOrEmpty(propertyName) && char.IsUpper(propertyName[0]))
|
||||
property.SetColumnName(char.ToLower(propertyName[0]) + propertyName.Substring(1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NamingStrategy.SnakeCase:
|
||||
foreach (var entity in modelBuilder.Model.GetEntityTypes())
|
||||
{
|
||||
// Converti il nome della tabella in snake_case
|
||||
string tableName = entity.GetTableName();
|
||||
if (!string.IsNullOrEmpty(tableName))
|
||||
entity.SetTableName(ConvertToSnakeCase(tableName));
|
||||
|
||||
// Converti i nomi delle proprietà in snake_case
|
||||
foreach (var property in entity.GetProperties())
|
||||
{
|
||||
string propertyName = property.GetColumnName();
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
property.SetColumnName(ConvertToSnakeCase(propertyName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private string ConvertToSnakeCase(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
|
||||
return string.Concat(input.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
|
||||
}
|
||||
|
||||
private void DiscoverEntities(ModelBuilder modelBuilder)
|
||||
{
|
||||
// Trova tutte le classi nel namespace specificato che potrebbero essere entità
|
||||
var entityTypes = _entityAssembly.GetTypes()
|
||||
.Where(t => !string.IsNullOrEmpty(_entityNamespace)
|
||||
? t.Namespace == _entityNamespace
|
||||
: true)
|
||||
.Where(t => t.IsClass && !t.IsAbstract && t.GetConstructor(Type.EmptyTypes) != null)
|
||||
.ToList();
|
||||
|
||||
// Metodo generico per aggiungere entità al modello
|
||||
var entityMethod = typeof(ModelBuilder).GetMethod("Entity", new Type[0]);
|
||||
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
// Usa reflection per chiamare il metodo generico Entity<T>()
|
||||
var genericMethod = entityMethod.MakeGenericMethod(entityType);
|
||||
genericMethod.Invoke(modelBuilder, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user