first commit
This commit is contained in:
87
RS_system/Data/ApplicationDbContext.cs
Normal file
87
RS_system/Data/ApplicationDbContext.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Rs_system.Models;
|
||||
|
||||
namespace Rs_system.Data;
|
||||
|
||||
public class ApplicationDbContext : DbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<Persona> Personas { get; set; }
|
||||
public DbSet<Usuario> Usuarios { get; set; }
|
||||
public DbSet<RolSistema> RolesSistema { get; set; }
|
||||
public DbSet<RolUsuario> RolesUsuario { get; set; }
|
||||
public DbSet<Permiso> Permisos { get; set; }
|
||||
public DbSet<Modulo> Modulos { get; set; }
|
||||
public DbSet<RolPermiso> RolesPermisos { get; set; }
|
||||
|
||||
public DbSet<ConfiguracionSistema> Configuraciones { get; set; }
|
||||
|
||||
public DbSet<AsistenciaCulto> AsistenciasCulto { get; set; }
|
||||
|
||||
// Offerings module
|
||||
public DbSet<RegistroCulto> RegistrosCulto { get; set; }
|
||||
public DbSet<Ofrenda> Ofrendas { get; set; }
|
||||
public DbSet<DescuentoOfrenda> DescuentosOfrenda { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// Configure composite key for RolUsuario
|
||||
modelBuilder.Entity<RolUsuario>()
|
||||
.HasKey(ru => new { ru.UsuarioId, ru.RolId });
|
||||
|
||||
// Configure relationships
|
||||
modelBuilder.Entity<RolUsuario>()
|
||||
.HasOne(ru => ru.Usuario)
|
||||
.WithMany(u => u.RolesUsuario)
|
||||
.HasForeignKey(ru => ru.UsuarioId);
|
||||
|
||||
modelBuilder.Entity<RolUsuario>()
|
||||
.HasOne(ru => ru.Rol)
|
||||
.WithMany(r => r.RolesUsuario)
|
||||
.HasForeignKey(ru => ru.RolId);
|
||||
|
||||
// Configure composite key for RolPermiso
|
||||
modelBuilder.Entity<RolPermiso>()
|
||||
.HasKey(rp => new { rp.RolId, rp.PermisoId });
|
||||
|
||||
modelBuilder.Entity<RolPermiso>()
|
||||
.HasOne(rp => rp.Rol)
|
||||
.WithMany(r => r.RolesPermisos)
|
||||
.HasForeignKey(rp => rp.RolId);
|
||||
|
||||
modelBuilder.Entity<RolPermiso>()
|
||||
.HasOne(rp => rp.Permiso)
|
||||
.WithMany()
|
||||
.HasForeignKey(rp => rp.PermisoId);
|
||||
|
||||
modelBuilder.Entity<Permiso>()
|
||||
.HasOne(p => p.Modulo)
|
||||
.WithMany(m => m.Permisos)
|
||||
.HasForeignKey(p => p.ModuloId);
|
||||
|
||||
modelBuilder.Entity<Usuario>()
|
||||
.HasOne(u => u.Persona)
|
||||
.WithMany()
|
||||
.HasForeignKey(u => u.PersonaId);
|
||||
|
||||
// Global configuration: Convert all dates to UTC when saving
|
||||
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
|
||||
{
|
||||
var properties = entityType.GetProperties()
|
||||
.Where(p => p.ClrType == typeof(DateTime) || p.ClrType == typeof(DateTime?));
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
property.SetValueConverter(new Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<DateTime, DateTime>(
|
||||
v => v.Kind == DateTimeKind.Utc ? v : DateTime.SpecifyKind(v, DateTimeKind.Utc),
|
||||
v => v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
RS_system/Data/DbContextOptimizationExtensions.cs
Normal file
42
RS_system/Data/DbContextOptimizationExtensions.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Rs_system.Data;
|
||||
|
||||
public static class DbContextOptimizationExtensions
|
||||
{
|
||||
public static IQueryable<T> AsNoTrackingWithIdentityResolution<T>(this IQueryable<T> query) where T : class
|
||||
{
|
||||
return query.AsNoTrackingWithIdentityResolution();
|
||||
}
|
||||
|
||||
public static IQueryable<T> AsSplitQuery<T>(this IQueryable<T> query) where T : class
|
||||
{
|
||||
return query.AsSplitQuery();
|
||||
}
|
||||
|
||||
public static IQueryable<T> TagWith<T>(this IQueryable<T> query, string comment) where T : class
|
||||
{
|
||||
return query.TagWith(comment);
|
||||
}
|
||||
|
||||
public static async Task<List<T>> ToListWithCountAsync<T>(this IQueryable<T> query, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = await query.ToListAsync(cancellationToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<T?> FirstOrDefaultNoTrackingAsync<T>(this IQueryable<T> query, CancellationToken cancellationToken = default) where T : class
|
||||
{
|
||||
return await query.AsNoTracking().FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public static async Task<bool> AnyNoTrackingAsync<T>(this IQueryable<T> query, CancellationToken cancellationToken = default) where T : class
|
||||
{
|
||||
return await query.AsNoTracking().AnyAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public static async Task<int> CountNoTrackingAsync<T>(this IQueryable<T> query, CancellationToken cancellationToken = default) where T : class
|
||||
{
|
||||
return await query.AsNoTracking().CountAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
39
RS_system/Data/PostgresQueryExecutor.cs
Normal file
39
RS_system/Data/PostgresQueryExecutor.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Npgsql;
|
||||
|
||||
namespace Rs_system.Data;
|
||||
|
||||
public static class PostgresQueryExecutor
|
||||
{
|
||||
public static async Task<List<T>> ExecuteQueryAsync<T>(
|
||||
DbContext context,
|
||||
string sql,
|
||||
Func<NpgsqlDataReader, T> map,
|
||||
Action<NpgsqlParameterCollection>? parameters = null
|
||||
)
|
||||
{
|
||||
var conn = (NpgsqlConnection)context.Database.GetDbConnection();
|
||||
|
||||
if (conn.State != ConnectionState.Open)
|
||||
await conn.OpenAsync();
|
||||
|
||||
await using var cmd = new NpgsqlCommand(sql, conn);
|
||||
|
||||
var currentTx = context.Database.CurrentTransaction;
|
||||
if (currentTx != null)
|
||||
cmd.Transaction = (NpgsqlTransaction)currentTx.GetDbTransaction();
|
||||
|
||||
parameters?.Invoke(cmd.Parameters);
|
||||
|
||||
var results = new List<T>();
|
||||
await using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
results.Add(map(reader));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
36
RS_system/Data/PostgresScalarExecutor.cs
Normal file
36
RS_system/Data/PostgresScalarExecutor.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Npgsql;
|
||||
|
||||
namespace Rs_system.Data;
|
||||
|
||||
public static class PostgresScalarExecutor
|
||||
{
|
||||
public static async Task<T> ExecuteAsync<T>(
|
||||
DbContext context,
|
||||
string sql,
|
||||
Action<NpgsqlParameterCollection>? parameters = null
|
||||
)
|
||||
{
|
||||
var conn = (NpgsqlConnection)context.Database.GetDbConnection();
|
||||
|
||||
if (conn.State != ConnectionState.Open)
|
||||
await conn.OpenAsync();
|
||||
|
||||
await using var cmd = new NpgsqlCommand(sql, conn);
|
||||
|
||||
var currentTx = context.Database.CurrentTransaction;
|
||||
if (currentTx != null)
|
||||
cmd.Transaction = (NpgsqlTransaction)currentTx.GetDbTransaction();
|
||||
|
||||
parameters?.Invoke(cmd.Parameters);
|
||||
|
||||
var result = await cmd.ExecuteScalarAsync();
|
||||
|
||||
if (result == null || result == DBNull.Value)
|
||||
throw new InvalidOperationException("La consulta escalar no devolvió ningún valor.");
|
||||
|
||||
return (T)Convert.ChangeType(result, typeof(T));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user