Nosabit.Adapters.Persistence.SqlServer 1.2.4

dotnet add package Nosabit.Adapters.Persistence.SqlServer --version 1.2.4                
NuGet\Install-Package Nosabit.Adapters.Persistence.SqlServer -Version 1.2.4                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nosabit.Adapters.Persistence.SqlServer" Version="1.2.4" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Nosabit.Adapters.Persistence.SqlServer --version 1.2.4                
#r "nuget: Nosabit.Adapters.Persistence.SqlServer, 1.2.4"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Nosabit.Adapters.Persistence.SqlServer as a Cake Addin
#addin nuget:?package=Nosabit.Adapters.Persistence.SqlServer&version=1.2.4

// Install Nosabit.Adapters.Persistence.SqlServer as a Cake Tool
#tool nuget:?package=Nosabit.Adapters.Persistence.SqlServer&version=1.2.4                

Nosabit.Adapters.Persistence.SqlServer

Implementación completa para acceso a datos SQL Server utilizando Dapper. Proporciona una implementación eficiente y segura para trabajar con procedimientos almacenados, realizar consultas complejas, mapeo de múltiples entidades y soporte para operaciones paginadas.

NuGet License: MIT

Instalación

Package Manager

Install-Package Nosabit.Adapters.Persistence.SqlServer

.NET CLI

dotnet add package Nosabit.Adapters.Persistence.SqlServer

PackageReference

<PackageReference Include="Nosabit.Adapters.Persistence.SqlServer"  />

Características principales

  • Implementación completa para SQL Server: Proporciona una implementación robusta de las abstracciones de acceso a datos
  • Alto rendimiento con Dapper: Aprovecha la velocidad y eficiencia de Dapper para operaciones de base de datos
  • Protección de cadenas de conexión: Encriptación automática de cadenas de conexión en entornos de producción
  • Manejo inteligente de errores: Captura y procesa errores SQL de manera adecuada
  • Soporte completo para procedimientos almacenados: Ejecución y mapeo eficiente de resultados de SPs
  • Mapeo avanzado de entidades: Facilita el mapeo de resultados complejos a objetos tipados
  • Consultas múltiples optimizadas: Soporte para ejecutar y mapear múltiples conjuntos de resultados en una sola llamada
  • Integración con ReactTable: Soporte nativo para paginación y ordenamiento con componentes React
  • Extensiones para inyección de dependencias: Métodos de extensión para configurar servicios fácilmente

Configuración

Este paquete se integra fácilmente en el pipeline de configuración de ASP.NET Core:

// En Program.cs
var builder = WebApplication.CreateBuilder(args);

// Agregar acceso a datos SQL Server con Dapper
builder.AddSqlServerWithDapper();

// Opcionalmente, habilitar la protección de cadenas de conexión en producción
// builder.AddSqlServerWithDapper(UseProtect: true);

// O especificar una cadena de conexión predeterminada diferente
// builder.AddSqlServerWithDapper(Default: "MiConexionPrincipal");

var app = builder.Build();

// Resto de la configuración...
app.Run();

Cadenas de conexión

Configura tus cadenas de conexión en appsettings.json:

{
  "ConnectionStrings": {
    "DefaultSqlServer": "Server=myserver;Database=mydb;User Id=myuser;Password=mypassword;TrustServerCertificate=True",
    "OtraConexion": "Server=otroserver;Database=otradb;User Id=myuser;Password=mypassword;TrustServerCertificate=True"
  }
}

Protección de cadenas de conexión

Cuando habilitas UseProtect: true, este paquete encripta automáticamente las cadenas de conexión en el archivo appsettings para mayor seguridad. Las cadenas de conexión encriptadas tendrán el prefijo "ENCR:".

Uso básico

Inyección de dependencias

public class ClienteService
{
    private readonly ISqlDataAccess _db;
    
    public ClienteService(ISqlDataAccess db)
    {
        _db = db;
    }
    
    // Métodos para trabajar con la base de datos...
}

Consultas básicas

// Obtener todos los registros
public async Task<IEnumerable<Cliente>> ObtenerTodosAsync()
{
    return await _db.QueryAsync<Cliente>("sp_ObtenerClientes");
}

// Obtener un registro por ID
public async Task<Cliente?> ObtenerPorIdAsync(int id)
{
    var parametros = new { Id = id };
    return await _db.QueryFirstAsync<Cliente>("sp_ObtenerClientePorId", parametros);
}

Ejecutar procedimientos almacenados

// Insertar un registro
public async Task<DBEntity> GuardarClienteAsync(Cliente cliente)
{
    return await _db.ExecuteAsync("sp_InsertarCliente", cliente);
}

// Ejecutar con parámetro de salida
public async Task<int> InsertarConIdAsync(Cliente cliente)
{
    int idGenerado = 0;
    
    await _db.ExecuteAsync("sp_InsertarCliente", parameters =>
    {
        idGenerado = parameters.Get<int>("IdGenerado");
    }, cliente);
    
    return idGenerado;
}

// Obtener el último registro insertado
public async Task<Cliente?> InsertarYObtenerAsync(Cliente cliente)
{
    var resultado = await _db.ExecuteGetLastInsertAsync<Cliente>("sp_InsertarCliente", cliente);
    if (resultado.CodeError != 0)
    {
        // Manejar error
        throw new Exception(resultado.MsgError);
    }
    return resultado.LastInsert;
}

Consultas con múltiples conjuntos de resultados

public async Task<(Cliente, IEnumerable<Pedido>)> ObtenerClienteConPedidosAsync(int id)
{
    var parametros = new { Id = id };
    
    return await _db.QueryMulti<Cliente, IEnumerable<Pedido>>(
        "sp_ObtenerClienteConPedidos",
        async reader => {
            var cliente = await reader.ReadFirstOrDefaultAsync<Cliente>();
            var pedidos = await reader.ReadAsync<Pedido>();
            return (cliente, pedidos);
        },
        parametros
    );
}

Consultas con mapeo personalizado

public async Task<IEnumerable<Cliente>> ObtenerClientesConDireccionesAsync()
{
    return await _db.QueryMapAsync<Cliente, Direccion>(
        "sp_ObtenerClientesConDirecciones",
        "Id", // Columna para hacer el split/join
        (cliente, direccion) => {
            cliente.Direccion = direccion;
            return cliente;
        }
    );
}

Integración con ReactTable

[HttpPost("api/clientes/tabla")]
public async Task<IActionResult> ObtenerTablaClientes()
{
    // Crear objeto de solicitud a partir de la petición HTTP
    var request = new ReactTableRequestDto(Request);
    
    // Parámetros adicionales si son necesarios
    var parametrosAdicionales = new { Activo = true };
    
    // Consultar con soporte para ReactTable
    var resultado = await _db.ReactTableQuery<ClienteDto>(
        "sp_ObtenerClientesTabla", 
        request, 
        parametrosAdicionales
    );
    
    return Ok(resultado);
}

Uso de parámetros dinámicos

public async Task<IEnumerable<Cliente>> BuscarClientesAsync(ClienteFiltroDto filtro)
{
    // Convertir DTO a DynamicParameters para mayor flexibilidad
    var parametros = _db.UseParamerter(filtro);
    
    // Opcional: agregar parámetros adicionales
    parametros.Add("ParametroAdicional", "valor");
    
    return await _db.QueryAsync<Cliente>("sp_BuscarClientes", parametros);
}

// Alternativa usando la extensión
public async Task<IEnumerable<Cliente>> BuscarClientesAlternativaAsync(ClienteFiltroDto filtro)
{
    var parametros = new DynamicParameters();
    parametros.UseParamerter(filtro); // Extensión de método
    
    return await _db.QueryAsync<Cliente>("sp_BuscarClientes", parametros);
}

Manejo de errores

La implementación proporciona manejo inteligente de errores SQL:

try
{
    var result = await _db.ExecuteAsync("sp_OperacionRiesgosa", parametros);
    
    if (result.CodeError != 0)
    {
        // Manejo de error específico devuelto por el procedimiento almacenado
        Console.WriteLine($"Error: {result.MsgError}");
        return false;
    }
    
    return true;
}
catch (SqlDataAccessException ex)
{
    // Manejo de excepciones específicas del acceso a datos
    Console.WriteLine($"Error de acceso a datos: {ex.Message}");
    return false;
}
catch (Exception ex)
{
    // Manejo de otras excepciones
    Console.WriteLine($"Error general: {ex.Message}");
    return false;
}

Uso con distintas cadenas de conexión

Puedes especificar qué cadena de conexión usar para cada operación:

// Usar la cadena de conexión predeterminada
var clientes = await _db.QueryAsync<Cliente>("sp_ObtenerClientes");

// Especificar una cadena de conexión diferente
var productos = await _db.QueryAsync<Producto>("sp_ObtenerProductos", 
    connId: "OtraConexion");

Mejores prácticas

  1. Siempre use procedimientos almacenados: Este paquete está optimizado para trabajar con SPs.
  2. Utilice las sobrecargas con parámetros de salida cuando necesite recuperar valores del procedimiento.
  3. Maneje adecuadamente los errores: Verifique los códigos de error y mensajes devueltos.
  4. Use ReactTableQuery para tablas grandes: Proporciona paginación optimizada del lado del servidor.
  5. Aplique la protección de cadenas de conexión en entornos de producción.
  6. Prefiera consultas tipadas sobre consultas dinámicas para un mejor rendimiento y seguridad.
  7. Utilice la transacción de SQL dentro del procedimiento almacenado en lugar de gestionar transacciones desde código.

Dependencias

  • Nosabit.Core: Proporciona tipos base como DBEntity
  • Nosabit.Adapters.Persistence.SqlServer.Abstractions: Define las interfaces implementadas
  • Dapper: ORM de alto rendimiento
  • Dapper.Mapper: Extensiones para mapeo de resultados
  • Microsoft.Data.SqlClient: Proveedor de acceso a datos para SQL Server

Requisitos

  • .NET 6.0 o superior
  • SQL Server 2016 o superior

Licencia

Este proyecto está licenciado bajo la Licencia MIT.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.4 225 3/24/2025
1.2.3 217 3/23/2025
1.2.1 130 3/23/2025
1.2.0 128 3/23/2025
1.1.5 130 3/22/2025
1.1.4 127 3/22/2025
1.1.3 53 3/21/2025
1.1.2 104 3/21/2025
1.1.1 100 3/21/2025
1.1.0 112 3/21/2025