LibraryDBApi 1.2.0

dotnet add package LibraryDBApi --version 1.2.0
                    
NuGet\Install-Package LibraryDBApi -Version 1.2.0
                    
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="LibraryDBApi" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LibraryDBApi" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="LibraryDBApi" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LibraryDBApi --version 1.2.0
                    
#r "nuget: LibraryDBApi, 1.2.0"
                    
#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.
#:package LibraryDBApi@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LibraryDBApi&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=LibraryDBApi&version=1.2.0
                    
Install as a Cake Tool

LibraryDBApi - API Innovadora para Procedimientos Almacenados y Operaciones Masivas

Una biblioteca .NET 9.0 revolucionaria que automatiza llamadas a procedimientos almacenados y operaciones masivas en bases de datos SQL Server con mapeo automático de tipos y optimizaciones avanzadas.

🚀 Características Principales

✨ Procedimientos Almacenados Inteligentes

  • Mapeo automático: Convierte automáticamente propiedades de modelos C# en parámetros de procedimientos almacenados
  • Filtrado inteligente: Solo usa propiedades compatibles con los parámetros del procedimiento
  • Resultados tipados (IEnumerable): Mapea automáticamente los resultados a colecciones IEnumerable<T> de modelos C# con coincidencia flexible
  • API simplificada: Especifica solo el tipo de elemento (T), el resultado es siempre una colección (IEnumerable<T>)
  • Parámetros unificados: Modelo único StoredProcedureParameters que incluye todos los parámetros necesarios

🔥 Operaciones Masivas Ultra-Rápidas

  • Inserción masiva: Una sola conexión con procesamiento por lotes
  • Actualización masiva: Una sola conexión con mapeo automático
  • Mapeo automático: Detecta columnas de tabla y propiedades del modelo
  • Procesamiento por lotes: Configurable para optimizar rendimiento
  • Manejo de identidad: Opción para ignorar columnas de identidad automáticamente

🎯 Mapeo Avanzado

  • Coincidencia flexible: Ignora mayúsculas/minúsculas y caracteres especiales
  • Atributos personalizados: Control total sobre el mapeo
  • Conversiones automáticas: Manejo inteligente de tipos de datos
  • Manejo de errores robusto: Valores por defecto y recuperación automática

📦 Instalación

Para instalar la librería en tu proyecto .NET:

dotnet add package LibraryDBApi
# O si necesitas una versión específica:
# dotnet add package LibraryDBApi --version <version>

🎯 Uso Rápido

Procedimientos Almacenados con Parámetros Unificados

// Configuración (asumiendo que tu DataService ya obtiene la cadena de conexión)
var dataService = new DataService(configuration); // Instancia de tu servicio

// 1. Procedimiento simple sin parámetros
var parameters = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "ObtenerTodosLosClientes"
};
var resultadoClientes = await dataService.EjecutarProcedimientoAsync<Cliente>(parameters);

// 2. Procedimiento con paginación
var parametersPaginados = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "ObtenerClientes",
    ModelPaginacion = new ModelPaginacion
    {
        PageNumber = 1,
        PageSize = 10
    }
};
var clientesPaginados = await dataService.EjecutarProcedimientoAsync<Cliente>(parametersPaginados);

// 3. Procedimiento con modelo de parámetros
var parametrosBusqueda = new { Nombre = "Juan", Edad = 25 };
var parametersConModelo = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "BuscarClientes",
    Model = parametrosBusqueda,
    ModelPaginacion = new ModelPaginacion
    {
        PageNumber = 1,
        PageSize = 20
    }
};
var clientesBuscados = await dataService.EjecutarProcedimientoAsync<Cliente>(parametersConModelo);

// 4. Procedimiento con filtro adicional
var parametersConFiltro = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "BuscarClientes",
    Model = parametrosBusqueda,
    ModelPaginacion = new ModelPaginacion
    {
        PageNumber = 1,
        PageSize = 20,
        Filter = "activos" // Filtro adicional como string
    }
};
var clientesFiltrados = await dataService.EjecutarProcedimientoAsync<Cliente>(parametersConFiltro);

// 5. Usando constructor con parámetros
var modelPaginacion = new ModelPaginacion(
    pageNumber: 1,
    pageSize: 20,
    filter: "activos"
);

var parametersConstructor = new StoredProcedureParameters(
    connectionString: "Server=myServer;Database=myDB;Trusted_Connection=true;",
    procedureName: "BuscarClientes",
    model: parametrosBusqueda,
    modelPaginacion: modelPaginacion
);
var resultadoConstructor = await dataService.EjecutarProcedimientoAsync<Cliente>(parametersConstructor);

// 6. Solo con filtro (sin paginación)
var parametersSoloFiltro = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "BuscarClientes",
    ModelPaginacion = new ModelPaginacion
    {
        Filter = "activos"
    }
};
var clientesFiltradosSolo = await dataService.EjecutarProcedimientoAsync<Cliente>(parametersSoloFiltro);

Operaciones Masivas con Procedimientos Almacenados

// Inserción masiva usando procedimiento almacenado
var nuevosClientes = new List<Cliente>
{
    new Cliente { Nombre = "Juan Pérez", Email = "juan@email.com", Activo = true },
    new Cliente { Nombre = "María García", Email = "maria@email.com", Activo = true },
    new Cliente { Nombre = "Carlos López", Email = "carlos@email.com", Activo = false }
};

var parametrosInsercion = new BulkInsertParameters(
    connectionString: connectionString,
    procedureName: "sp_BulkInsertClientes",  // Procedimiento almacenado
    data: nuevosClientes,
    batchSize: 1000,
    ignoreIdentityColumns: true
);

var resultadoInsercion = await dataService.InsertarDatosMasivamenteAsync<Cliente>(parametrosInsercion);

// Actualización masiva usando procedimiento almacenado
var clientesParaActualizar = new List<Cliente>
{
    new Cliente { Id = 1, Nombre = "Juan Actualizado", Email = "juan@email.com" },
    new Cliente { Id = 2, Nombre = "María Actualizada", Email = "maria@email.com" }
};

var parametrosActualizacion = new BulkUpdateParameters(
    connectionString: connectionString,
    procedureName: "sp_BulkUpdateClientes",  // Procedimiento almacenado
    data: clientesParaActualizar,
    keyColumn: "Id",
    batchSize: 1000
);

var resultadoActualizacion = await dataService.ActualizarDatosMasivamenteAsync<Cliente>(parametrosActualizacion);

// Verificar resultados
if (resultadoInsercion.IsSuccess)
{
    Console.WriteLine($"✅ {resultadoInsercion.RowsAffected} registros insertados en {resultadoInsercion.ExecutionTimeMs}ms");
}

if (resultadoActualizacion.IsSuccess)
{
    Console.WriteLine($"✅ {resultadoActualizacion.RowsAffected} registros actualizados en {resultadoActualizacion.ExecutionTimeMs}ms");
}

⚡ Operaciones Masivas Avanzadas con Procedimientos Almacenados

Inserción Masiva con Procedimientos Almacenados

// Inserción masiva usando procedimiento almacenado con lógica de negocio
var nuevosProductos = new List<Producto>
{
    new Producto { Nombre = "Laptop Gaming", Precio = 1299.99m, Stock = 10, Categoria = "Electrónicos" },
    new Producto { Nombre = "Mouse Inalámbrico", Precio = 29.99m, Stock = 50, Categoria = "Accesorios" },
    new Producto { Nombre = "Teclado Mecánico", Precio = 89.99m, Stock = 25, Categoria = "Accesorios" }
};

var parametrosInsercion = new BulkInsertParameters(
    connectionString: connectionString,
    procedureName: "sp_BulkInsertProductos",  // Procedimiento con validaciones y lógica
    data: nuevosProductos,
    batchSize: 1000,
    ignoreIdentityColumns: true
);

var resultado = await dataService.InsertarDatosMasivamenteAsync<Producto>(parametrosInsercion);

if (resultado.IsSuccess)
{
    Console.WriteLine($"✅ {resultado.RowsAffected} registros insertados en {resultado.ExecutionTimeMs}ms");
}
else
{
    Console.WriteLine($"❌ Error: {resultado.Message}");
}

Actualización Masiva con Procedimientos Almacenados

// Actualización masiva usando procedimiento almacenado con validaciones
var clientesParaActualizar = new List<Cliente>
{
    new Cliente { Id = 1, Nombre = "Juan Pérez Actualizado", Email = "juan.actualizado@email.com" },
    new Cliente { Id = 2, Nombre = "María García Actualizada", Email = "maria.actualizada@email.com" },
    new Cliente { Id = 3, Nombre = "Carlos López Actualizado", Email = "carlos.actualizado@email.com" }
};

var parametrosActualizacion = new BulkUpdateParameters(
    connectionString: connectionString,
    procedureName: "sp_BulkUpdateClientes",  // Procedimiento con validaciones y auditoría
    data: clientesParaActualizar,
    keyColumn: "Id",
    batchSize: 1000
);

var resultado = await dataService.ActualizarDatosMasivamenteAsync<Cliente>(parametrosActualizacion);

if (resultado.IsSuccess)
{
    Console.WriteLine($"✅ {resultado.RowsAffected} registros actualizados en {resultado.ExecutionTimeMs}ms");
}
else
{
    Console.WriteLine($"❌ Error: {resultado.Message}");
}

Características de las Operaciones Masivas con Procedimientos Almacenados

  • Lógica de negocio: Los procedimientos pueden incluir validaciones, auditoría, y reglas de negocio
  • Transacciones automáticas: Control de transacciones dentro del procedimiento almacenado
  • Optimización de rendimiento: Procedimientos compilados y optimizados por SQL Server
  • Seguridad mejorada: Protección contra inyección SQL y control de acceso granular
  • Mapeo automático: Detecta automáticamente los parámetros del procedimiento y las propiedades del modelo
  • Procesamiento por lotes: Divide los datos en lotes configurables para mejor rendimiento
  • Manejo de errores robusto: Captura y reporta errores detallados del procedimiento

Ejemplos de Procedimientos Almacenados

Procedimiento de Inserción Masiva
CREATE PROCEDURE sp_BulkInsertClientes
    @Data NVARCHAR(MAX),           -- JSON con los datos del batch
    @BatchSize INT = 1000,         -- Tamaño del lote
    @IgnoreIdentityColumns BIT = 1 -- Ignorar columnas de identidad
AS
BEGIN
    SET NOCOUNT ON;
    
    BEGIN TRY
        BEGIN TRANSACTION;
        
        -- Insertar datos desde JSON
        INSERT INTO Clientes (Nombre, Email, Activo, FechaCreacion)
        SELECT 
            JSON_VALUE(value, '$.Nombre'),
            JSON_VALUE(value, '$.Email'),
            CAST(JSON_VALUE(value, '$.Activo') AS BIT),
            GETDATE()
        FROM OPENJSON(@Data);
        
        COMMIT TRANSACTION;
        
        -- Retornar número de filas afectadas
        SELECT @@ROWCOUNT AS RowsAffected;
        
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW;
    END CATCH
END
Procedimiento de Actualización Masiva
CREATE PROCEDURE sp_BulkUpdateClientes
    @Data NVARCHAR(MAX),    -- JSON con los datos del batch
    @KeyColumn NVARCHAR(50), -- Columna clave
    @BatchSize INT = 1000    -- Tamaño del lote
AS
BEGIN
    SET NOCOUNT ON;
    
    BEGIN TRY
        BEGIN TRANSACTION;
        
        -- Actualizar datos desde JSON
        UPDATE c SET
            c.Nombre = JSON_VALUE(j.value, '$.Nombre'),
            c.Email = JSON_VALUE(j.value, '$.Email'),
            c.FechaModificacion = GETDATE()
        FROM Clientes c
        INNER JOIN OPENJSON(@Data) j 
            ON c.Id = CAST(JSON_VALUE(j.value, '$.Id') AS INT);
        
        COMMIT TRANSACTION;
        
        -- Retornar número de filas afectadas
        SELECT @@ROWCOUNT AS RowsAffected;
        
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW;
    END CATCH
END

🛠️ Configuración y Mejores Prácticas

Configuración de Tamaño de Lote

// Para operaciones pequeñas (menos de 1000 registros)
var resultado = await dataService.InsertarDatosMasivamenteAsync(
    connectionString, "Tabla", datos, batchSize: 100
);

// Para operaciones grandes (más de 10000 registros)
var resultado = await dataService.InsertarDatosMasivamenteAsync(
    connectionString, "Tabla", datos, batchSize: 5000
);

// Para operaciones con columnas de identidad personalizadas
var resultado = await dataService.InsertarDatosMasivamenteAsync(
    connectionString, "Tabla", datos, batchSize: 1000, ignoreIdentityColumns: false
);

🔍 Manejo de Resultados

// Ahora el método EjecutarProcedimientoAsync<T> siempre retorna StoredProcedureResult<IEnumerable<T>>
var parameters = new StoredProcedureParameters
{
    ConnectionString = "Server=myServer;Database=myDB;Trusted_Connection=true;",
    ProcedureName = "BuscarClientes",
    Model = parametrosBusqueda
};

var resultadoConsulta = await dataService.EjecutarProcedimientoAsync<Cliente>(parameters);

if (resultadoConsulta.IsSuccess)
{
    var clientes = resultadoConsulta.Data; // clientes es de tipo IEnumerable<Cliente>
    Console.WriteLine($"Se encontraron {clientes.Count()} clientes");
    
    // Información de paginación si está disponible
    if (resultadoConsulta.TotalRecords.HasValue)
    {
        Console.WriteLine($"Total de registros: {resultadoConsulta.TotalRecords}");
        Console.WriteLine($"Página actual: {resultadoConsulta.PageNumber}");
        Console.WriteLine($"Tamaño de página: {resultadoConsulta.PageSize}");
    }
    
    // Puedes iterar sobre 'clientes' o usar métodos LINQ como .ToList(), .FirstOrDefault(), etc.
    var primerCliente = clientes.FirstOrDefault();
}
else
{
    Console.WriteLine($"Error: {resultadoConsulta.Message}");
}

🚀 Ventajas Clave

  1. Simplicidad: API intuitiva que infere automáticamente los tipos y siempre retorna colecciones.
  2. Rendimiento: Operaciones masivas optimizadas para máxima velocidad.
  3. Flexibilidad: Mapeo automático con opciones de personalización.
  4. Robustez: Manejo de errores avanzado y recuperación automática.
  5. Unificación: Un solo modelo de parámetros para todos los escenarios.

📊 Comparación de Rendimiento

Operación Código Tradicional LibraryDBApi Mejora
1000 inserciones 15 segundos 0.5 segundos 30x más rápido
1000 actualizaciones 25 segundos 2 segundos 12x más rápido
Mapeo de resultados 50 líneas 1 línea 50x menos código
Procedimientos almacenados 20 líneas 3 líneas 7x menos código

📦 Publicación del Paquete NuGet

Sigue estos pasos para crear y publicar el paquete NuGet de LibraryDBApi:

1. Crear el paquete .nupkg

Primero, asegúrate de que tu proyecto tenga la versión correcta (por ejemplo, 1.0.1 en LibraryDBApi.csproj si aún no lo has hecho, aunque la creación del paquete inferirá la versión del csproj). Luego, ejecuta el siguiente comando en la raíz de tu proyecto LibraryDBApi:

dotnet pack --configuration Release /p:Version=1.0.1

📚 API Reference

IDataService

EjecutarProcedimientoAsync<TResult>(StoredProcedureParameters)

Ejecuta un procedimiento almacenado usando parámetros unificados.

Parámetros:

  • parameters: Objeto StoredProcedureParameters con la configuración completa

Retorna: Task<StoredProcedureResult<IEnumerable<TResult>>>

EjecutarProcedimientoAsync<TResult>(string, string, ModelPaginacion)

Ejecuta un procedimiento almacenado sin modelo de parámetros.

Parámetros:

  • connectionString: Cadena de conexión a la base de datos
  • procedureName: Nombre del procedimiento almacenado
  • modelPaginacion: Modelo de paginación (opcional)

Retorna: Task<StoredProcedureResult<IEnumerable<TResult>>>

ActualizarDatosMasivamenteAsync<TModel>(BulkUpdateParameters)

Realiza una actualización masiva de datos usando procedimientos almacenados.

Parámetros:

  • parameters: Objeto BulkUpdateParameters con la configuración completa

Retorna: Task<BulkOperationResult>

InsertarDatosMasivamenteAsync<TModel>(BulkInsertParameters)

Realiza una inserción masiva de datos usando procedimientos almacenados.

Parámetros:

  • parameters: Objeto BulkInsertParameters con la configuración completa

Retorna: Task<BulkOperationResult>

Modelos Principales

StoredProcedureParameters

Modelo unificado para parámetros de procedimientos almacenados.

Propiedades:

  • ConnectionString: Cadena de conexión
  • ProcedureName: Nombre del procedimiento
  • Model: Modelo de parámetros (opcional)
  • ModelPaginacion: Configuración de paginación (opcional)
BulkOperationResult

Resultado de operaciones masivas.

Propiedades:

  • IsSuccess: Indica si la operación fue exitosa
  • Message: Mensaje de resultado
  • RowsAffected: Número de filas afectadas
  • ExecutionTimeMs: Tiempo de ejecución en milisegundos
  • BatchSize: Tamaño del lote procesado
  • Exception: Excepción capturada (si aplica)
ModelPaginacion

Configuración de paginación para procedimientos almacenados.

Propiedades:

  • PageNumber: Número de página
  • PageSize: Tamaño de página
  • Filter: Filtro adicional como string
BulkInsertParameters

Parámetros para operaciones de inserción masiva.

Propiedades:

  • ConnectionString: Cadena de conexión a la base de datos
  • ProcedureName: Nombre del procedimiento almacenado
  • Data: Lista de objetos a insertar
  • BatchSize: Tamaño del lote (opcional, por defecto 1000)
  • IgnoreIdentityColumns: Si debe ignorar columnas de identidad (opcional, por defecto true)
  • AdditionalParameters: Parámetros adicionales para el procedimiento (opcional)
BulkUpdateParameters

Parámetros para operaciones de actualización masiva.

Propiedades:

  • ConnectionString: Cadena de conexión a la base de datos
  • ProcedureName: Nombre del procedimiento almacenado
  • Data: Lista de objetos a actualizar
  • KeyColumn: Columna clave para identificar registros
  • BatchSize: Tamaño del lote (opcional, por defecto 1000)
  • AdditionalParameters: Parámetros adicionales para el procedimiento (opcional)
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.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.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.0 93 9/14/2025
1.1.1 132 9/9/2025