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
<PackageReference Include="Nosabit.Adapters.Persistence.SqlServer" Version="1.2.4" />
paket add Nosabit.Adapters.Persistence.SqlServer --version 1.2.4
#r "nuget: Nosabit.Adapters.Persistence.SqlServer, 1.2.4"
// 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.
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
- Siempre use procedimientos almacenados: Este paquete está optimizado para trabajar con SPs.
- Utilice las sobrecargas con parámetros de salida cuando necesite recuperar valores del procedimiento.
- Maneje adecuadamente los errores: Verifique los códigos de error y mensajes devueltos.
- Use ReactTableQuery para tablas grandes: Proporciona paginación optimizada del lado del servidor.
- Aplique la protección de cadenas de conexión en entornos de producción.
- Prefiera consultas tipadas sobre consultas dinámicas para un mejor rendimiento y seguridad.
- 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 | Versions 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. |
-
net9.0
- Dapper (>= 2.1.66)
- Dapper.Mapper (>= 2.0.0)
- Dapper.Transaction (>= 2.1.35)
- Microsoft.Data.SqlClient (>= 6.0.1)
- Nosabit.Adapters.Persistence.SqlServer.Abstractions (>= 1.2.4)
- Nosabit.Core (>= 1.2.1)
- System.Net.Http (>= 4.3.4)
- System.Text.RegularExpressions (>= 4.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.