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;
///
/// Implementazione di IExistingDatabaseManager basata su Entity Framework Core
///
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();
_options.DbContextConfigurator(optionsBuilder);
_context = new ExistingDatabaseContext(
optionsBuilder.Options,
_options.ModelConfigurator,
_options.EnableAutoDiscovery,
_options.EntityAssembly,
_options.EntityNamespace,
_options.NamingStrategy);
}
public async Task TestConnectionAsync()
{
try
{
return await _context.Database.CanConnectAsync();
}
catch
{
return false;
}
}
public async Task> GetAsync(
Expression> filter = null,
Func, IOrderedQueryable> orderBy = null,
string includeProperties = "",
int? skip = null,
int? take = null) where T : class
{
IQueryable query = _context.Set();
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 GetByIdAsync(object id) where T : class
{
return await _context.Set().FindAsync(id);
}
public async Task> ExecuteQueryAsync(string sql, params object[] parameters) where T : class
{
return await _context.Set().FromSqlRaw(sql, parameters).ToListAsync();
}
public async Task ExecuteCommandAsync(string sql, params object[] parameters)
{
return await _context.Database.ExecuteSqlRawAsync(sql, parameters);
}
public async Task>> GetDatabaseSchemaAsync()
{
// Assicurarsi che il contesto sia connesso
await _context.Database.OpenConnectionAsync();
var result = new Dictionary>();
// 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();
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();
}
}