MapSql 1.1.0

dotnet add package MapSql --version 1.1.0
                    
NuGet\Install-Package MapSql -Version 1.1.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="MapSql" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MapSql" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="MapSql" />
                    
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 MapSql --version 1.1.0
                    
#r "nuget: MapSql, 1.1.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 MapSql@1.1.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=MapSql&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=MapSql&version=1.1.0
                    
Install as a Cake Tool

MapSql - Guía de Uso

MapSql es una biblioteca ligera y eficiente para ejecutar Stored Procedures en SQL Server con mapeo automático de objetos. Incluye soporte completo para inyección de dependencias y múltiples formas de configuración.

🚀 Inicio Rápido

# 1. Instalar el paquete
dotnet add package MapSql

# 2. Configurar en Program.cs
using MapSql.Extensions;
builder.Services.AddMapSql(builder.Configuration);

# 3. Usar en tu código
public class UserService
{
    private readonly ISqlPort _sqlPort;

    public UserService(ISqlPort sqlPort) => _sqlPort = sqlPort;

    public async Task<List<User>> GetUsers()
    {
        return await _sqlPort.ExecuteStoredProcedureAsync<User>("sp_GetUsers");
    }
}

appsettings.json:

{
  "AppSettings": {
    "DatabaseConnection": "Server=localhost;Database=MyDB;Integrated Security=true;"
  }
}

📑 Tabla de Contenidos


Instalación

MapSql es una biblioteca ligera para ejecutar Stored Procedures en SQL Server con mapeo automático de objetos y soporte completo para inyección de dependencias.

Desde NuGet.org (Cuando esté publicado)

dotnet add package MapSql

O usando el Administrador de Paquetes de Visual Studio:

Install-Package MapSql

Desde Fuente Local (Para desarrollo/pruebas)

Si estás usando el paquete localmente antes de publicarlo en NuGet.org:

1. Compilar el paquete
# Opción A: Usar el script de PowerShell
cd c:\Users\luisp\source\repos\MapSql
.\build-nuget.ps1 -Action publish-local

# Opción B: Manualmente
cd c:\Users\luisp\source\repos\MapSql\MapSql
dotnet pack --configuration Release --output ./nupkg
2. Agregar la fuente local (solo una vez)
# Crear carpeta para paquetes locales
mkdir C:\LocalNuGetPackages

# Copiar el paquete
copy c:\Users\luisp\source\repos\MapSql\MapSql\nupkg\MapSql.1.0.0.nupkg C:\LocalNuGetPackages\

# Agregar fuente local a NuGet
dotnet nuget add source C:\LocalNuGetPackages --name "Local Packages"
3. Instalar en tu proyecto
cd C:\ruta\a\tu\proyecto
dotnet add package MapSql --version 1.0.0

Nota: Si usaste el script .\build-nuget.ps1 -Action publish-local, los pasos 1 y 2 ya se hicieron automáticamente.


Configuración de la Cadena de Conexión

La biblioteca MapSql ofrece dos formas de configurar la cadena de conexión, dependiendo de tus necesidades:


Opción 1: Uso Directo (Sin Inyección de Dependencias)

Esta opción es ideal para aplicaciones simples o cuando no estás usando el contenedor de inyección de dependencias de .NET.

using Infrastructure.DrivenAdapters.Repository;

// Crear instancia directamente pasando la cadena de conexión
var connectionString = "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;";
var repository = new SqlRepositoryAdapter(connectionString);

// Usar el repositorio
var result = await repository.ExecuteStoredProcedureAsync<MyModel>("sp_GetData");

Opción 2: Con Inyección de Dependencias (Recomendado para aplicaciones ASP.NET Core)

Esta opción es ideal para aplicaciones web o cuando ya estás usando el patrón de inyección de dependencias.

MapSql incluye métodos de extensión que simplifican la configuración. Hay 3 formas de usar la inyección de dependencias:

Forma 1: Usando appsettings.json (Recomendado)

Paso 1: Configurar appsettings.json

{
  "AppSettings": {
    "DatabaseConnection": "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;"
  }
}

Paso 2: Registrar en Program.cs

using MapSql.Extensions;

var builder = WebApplication.CreateBuilder(args);

// ✨ Forma simplificada usando el método de extensión
builder.Services.AddMapSql(builder.Configuration);

var app = builder.Build();

Si tu sección de configuración tiene un nombre diferente:

// Si en appsettings.json tienes "Database" en lugar de "AppSettings"
builder.Services.AddMapSql(builder.Configuration, "Database");

Forma 2: Usando cadena de conexión directa
using MapSql.Extensions;

var builder = WebApplication.CreateBuilder(args);

// ✨ Pasar la cadena de conexión directamente
var connectionString = "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;";
builder.Services.AddMapSql(connectionString);

var app = builder.Build();

Forma 3: Usando una factory function (Avanzado)

Útil cuando necesitas obtener la cadena de conexión de otra fuente o servicio:

using MapSql.Extensions;

var builder = WebApplication.CreateBuilder(args);

// ✨ Usar una función para obtener la cadena de conexión
builder.Services.AddMapSql(serviceProvider =>
{
    // Ejemplo: obtener de otro servicio
    var config = serviceProvider.GetRequiredService<IConfiguration>();
    return config.GetConnectionString("DefaultConnection");
});

var app = builder.Build();

Paso 3: Inyectar en tus servicios o controladores
public class MyService
{
    private readonly ISqlPort _sqlPort;

    public MyService(ISqlPort sqlPort)
    {
        _sqlPort = sqlPort;
    }

    public async Task<List<MyModel>> GetDataAsync()
    {
        return await _sqlPort.ExecuteStoredProcedureAsync<MyModel>("sp_GetData");
    }
}

Métodos Disponibles

1. ExecuteStoredProcedureAsync<T>

Ejecuta un stored procedure que devuelve una lista de objetos.

var users = await repository.ExecuteStoredProcedureAsync<User>("sp_GetUsers", new { Active = true });

2. ExecuteStoredProcedureSingleAsync<T>

Ejecuta un stored procedure que devuelve un único objeto.

var user = await repository.ExecuteStoredProcedureSingleAsync<User>("sp_GetUserById", new { Id = 123 });

3. ExecuteNonQueryAsync

Ejecuta un stored procedure que no devuelve resultados (INSERT, UPDATE, DELETE).

int rowsAffected = await repository.ExecuteNonQueryAsync("sp_UpdateUser", new { Id = 123, Name = "Juan" });

4. ExecuteStoredProcedureBoolAsync

Ejecuta un stored procedure que devuelve un valor booleano.

bool exists = await repository.ExecuteStoredProcedureBoolAsync("sp_UserExists", new { Email = "test@example.com" });

5. ExecuteStoredProcedureMultipleAsync

Ejecuta un stored procedure que devuelve múltiples conjuntos de resultados.

var resultTypes = new[] { typeof(User), typeof(Order), typeof(Product) };
var results = await repository.ExecuteStoredProcedureMultipleAsync("sp_GetDashboard", resultTypes);

var users = results[0].Cast<User>().ToList();
var orders = results[1].Cast<Order>().ToList();
var products = results[2].Cast<Product>().ToList();

6. ExecuteBulkInsertAsync

Ejecuta un stored procedure utilizando Table-Valued Parameters (TVP) para inserciones masivas a nivel de base de datos. Se puede pasar un DataTable o una lista genérica que será convertida automáticamente.

// Inserción masiva desde una lista de objetos
List<User> newUsers = GetNewUsers();
int rowsAffected = await repository.ExecuteBulkInsertAsync("sp_BulkInsertUsers", "@UsersTableParam", newUsers, "dbo.UserTableType");

Ejemplos Completos

Ejemplo con Aplicación de Consola

using Infrastructure.DrivenAdapters.Repository;

class Program
{
    static async Task Main(string[] args)
    {
        var connectionString = "Server=localhost;Database=TestDB;Integrated Security=true;";
        var repository = new SqlRepositoryAdapter(connectionString);

        // Obtener lista de usuarios
        var users = await repository.ExecuteStoredProcedureAsync<User>("sp_GetAllUsers");

        foreach (var user in users)
        {
            Console.WriteLine($"Usuario: {user.Name}");
        }
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Ejemplo con ASP.NET Core Web API

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private readonly ISqlPort _sqlPort;

    public UsersController(ISqlPort sqlPort)
    {
        _sqlPort = sqlPort;
    }

    [HttpGet]
    public async Task<ActionResult<List<User>>> GetUsers()
    {
        var users = await _sqlPort.ExecuteStoredProcedureAsync<User>("sp_GetAllUsers");
        return Ok(users);
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<User>> GetUser(int id)
    {
        var user = await _sqlPort.ExecuteStoredProcedureSingleAsync<User>("sp_GetUserById", new { Id = id });

        if (user == null)
            return NotFound();

        return Ok(user);
    }

    [HttpPost]
    public async Task<ActionResult> CreateUser(User user)
    {
        await _sqlPort.ExecuteNonQueryAsync("sp_CreateUser", new
        {
            Name = user.Name,
            Email = user.Email
        });

        return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
    }
}

Notas Importantes

  • ✅ La biblioteca mapea automáticamente las columnas del resultado a las propiedades de tus modelos
  • ✅ Los parámetros se pasan como objetos anónimos y se convierten automáticamente a parámetros SQL
  • ✅ Todas las operaciones son asíncronas para mejor rendimiento
  • ✅ La cadena de conexión es obligatoria y se valida en el constructor
  • ✅ Compatible con .NET 8.0+

Solución de Problemas

Error: "La cadena de conexión no puede ser nula o vacía"

Causa: No se proporcionó una cadena de conexión válida.

Solución:

  • Si usas el constructor directo, asegúrate de pasar una cadena de conexión válida
  • Si usas IOptions, verifica que appsettings.json tenga la sección AppSettings:DatabaseConnection configurada

Error: "La cadena de conexión no puede ser nula. Asegúrese de configurar AppSettings:DatabaseConnection"

Causa: Estás usando inyección de dependencias pero no configuraste AppSettings correctamente.

Solución:

// En Program.cs
builder.Services.Configure<AppSettings>(
    builder.Configuration.GetSection("AppSettings")
);

Licencia

MIT License

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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.1.0 54 6/4/2026
1.0.0 96 1/30/2026