Prima implementazione del servizio di connessione e scoperta del database
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using DataConnection.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace DataConnection.EF;
|
||||
|
||||
/// <summary>
|
||||
/// Implementazione di IExistingDatabaseManager basata su Entity Framework Core
|
||||
/// </summary>
|
||||
public class EFCoreDatabaseManager : IDatabaseManager
|
||||
{
|
||||
private readonly DbManagerOptions _options;
|
||||
private ExistingDatabaseContext _context;
|
||||
|
||||
public EFCoreDatabaseManager(DbManagerOptions options)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
InitializeContext();
|
||||
}
|
||||
|
||||
private void InitializeContext()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ExistingDatabaseContext>();
|
||||
_options.DbContextConfigurator(optionsBuilder);
|
||||
|
||||
_context = new ExistingDatabaseContext(
|
||||
optionsBuilder.Options,
|
||||
_options.ModelConfigurator,
|
||||
_options.EnableAutoDiscovery,
|
||||
_options.EntityAssembly,
|
||||
_options.EntityNamespace,
|
||||
_options.NamingStrategy);
|
||||
}
|
||||
|
||||
public async Task<bool> TestConnectionAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _context.Database.CanConnectAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<T>> GetAsync<T>(
|
||||
Expression<Func<T, bool>> filter = null,
|
||||
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
|
||||
string includeProperties = "",
|
||||
int? skip = null,
|
||||
int? take = null) where T : class
|
||||
{
|
||||
IQueryable<T> query = _context.Set<T>();
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
query = query.Where(filter);
|
||||
}
|
||||
|
||||
foreach (var includeProperty in includeProperties.Split
|
||||
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
query = query.Include(includeProperty);
|
||||
}
|
||||
|
||||
if (orderBy != null)
|
||||
{
|
||||
query = orderBy(query);
|
||||
}
|
||||
|
||||
if (skip.HasValue)
|
||||
{
|
||||
query = query.Skip(skip.Value);
|
||||
}
|
||||
|
||||
if (take.HasValue)
|
||||
{
|
||||
query = query.Take(take.Value);
|
||||
}
|
||||
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<T> GetByIdAsync<T>(object id) where T : class
|
||||
{
|
||||
return await _context.Set<T>().FindAsync(id);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<T>> ExecuteQueryAsync<T>(string sql, params object[] parameters) where T : class
|
||||
{
|
||||
return await _context.Set<T>().FromSqlRaw(sql, parameters).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> ExecuteCommandAsync(string sql, params object[] parameters)
|
||||
{
|
||||
return await _context.Database.ExecuteSqlRawAsync(sql, parameters);
|
||||
}
|
||||
|
||||
public async Task<IDictionary<string, IEnumerable<DbColumnInfo>>> GetDatabaseSchemaAsync()
|
||||
{
|
||||
// Assicurarsi che il contesto sia connesso
|
||||
await _context.Database.OpenConnectionAsync();
|
||||
|
||||
var result = new Dictionary<string, IEnumerable<DbColumnInfo>>();
|
||||
|
||||
// Ottiene tutte le entità dal modello
|
||||
var model = _context.Model;
|
||||
var entityTypes = model.GetEntityTypes().ToList();
|
||||
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
var tableName = entityType.GetTableName();
|
||||
var schemaName = entityType.GetSchema();
|
||||
var fullTableName = string.IsNullOrEmpty(schemaName) ? tableName : $"{schemaName}.{tableName}";
|
||||
|
||||
var columns = new List<DbColumnInfo>();
|
||||
|
||||
foreach (var property in entityType.GetProperties())
|
||||
{
|
||||
var columnInfo = new DbColumnInfo
|
||||
{
|
||||
Name = property.GetColumnName(),
|
||||
DataType = property.GetColumnType(),
|
||||
IsNullable = property.IsNullable,
|
||||
IsPrimaryKey = property.IsPrimaryKey()
|
||||
};
|
||||
|
||||
// Verifica se è una foreign key
|
||||
var foreignKeys = entityType.GetForeignKeys().Where(fk => fk.Properties.Contains(property));
|
||||
if (foreignKeys.Any())
|
||||
{
|
||||
var fk = foreignKeys.First();
|
||||
columnInfo.IsForeignKey = true;
|
||||
columnInfo.ReferencedTable = fk.PrincipalEntityType.GetTableName();
|
||||
columnInfo.ReferencedColumn = fk.PrincipalKey.Properties.First().GetColumnName();
|
||||
}
|
||||
|
||||
columns.Add(columnInfo);
|
||||
}
|
||||
|
||||
result.Add(fullTableName, columns);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_context?.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user