DBSQLClient 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package DBSQLClient --version 0.1.0
                    
NuGet\Install-Package DBSQLClient -Version 0.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="DBSQLClient" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DBSQLClient" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="DBSQLClient" />
                    
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 DBSQLClient --version 0.1.0
                    
#r "nuget: DBSQLClient, 0.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 DBSQLClient@0.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=DBSQLClient&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=DBSQLClient&version=0.1.0
                    
Install as a Cake Tool

⚡ Referencia Rápida - SqlParams

🎯 Cheat Sheet

using DBSQLClient.Servicio.Parameter;

📝 Sintaxis Rápida

Crear Parámetros

Código Descripción
SqlParams.Param("Name", value) Parámetro simple
SqlParams.AddParams(("N1", v1), ("N2", v2)) Múltiples parámetros
SqlParams.Int("Id", 123) Entero
SqlParams.String("Name", "Juan", 100) String con tamaño
SqlParams.Decimal("Price", 99.99m, 18, 2) Decimal con precisión
SqlParams.DateTime("Date", DateTime.Now) Fecha/hora
SqlParams.Bool("IsActive", true) Booleano
SqlParams.Guid("UserId", guid) GUID
SqlParams.OutParam("Result", SqlDbType.Int) Parámetro de salida

🔥 Ejemplos de 1 Línea

// Procedimiento simple
await service.ExecuteAsync("sp_GetUser", SqlParams.AddParams(("Id", 123)));

// Consulta con filtro
await service.QueryAsync("SELECT * FROM Users WHERE Id = @Id", 
    SqlParams.AddParams(("Id", userId)));

// Con múltiples parámetros
await service.ExecuteAsync("sp_UpdateUser", SqlParams.AddParams(
    ("Id", 123), ("Name", "Juan"), ("Email", "juan@email.com")
));

📊 Métodos Disponibles

Creación Básica

SqlParams.Param(name, value)
SqlParams.Param(name, value, type)
SqlParams.Param(name, value, type, size)

Por Tipo

SqlParams.Int(name, value)
SqlParams.String(name, value, size = SqlParams.Max)
SqlParams.Decimal(name, value, precision = 18, scale = 2)
SqlParams.DateTime(name, value)
SqlParams.DateTime2(name, value)
SqlParams.Date(name, value)
SqlParams.Bool(name, value)
SqlParams.Guid(name, value)
SqlParams.Binary(name, value)

Salida

SqlParams.OutParam(name, type)
SqlParams.InOutParam(name, value, type)
SqlParams.ReturnParam()

Nulos explícitos

SqlParams.DbNull(name, type)
SqlParams.DbNull(name, type, size)

Múltiples

SqlParams.AddParams((name, value), ...)
SqlParams.FromDictionary(dict)
SqlParams.FromObject(obj)
new SqlParameterBuilder().AddRange(parametrosYaConstruidos)

Obtener Valores

SqlParams.GetOutputValue<T>(parameter)

🏗️ Builder Pattern

var parametros = new SqlParameterBuilder()
    .AddInt("Id", 123)
    .AddString("Name", "Juan")
    .AddDecimal("Price", 99.99m)
    .AddOutput("Result", SqlDbType.Int)
    .AddRange(SqlParams.AddParams(("Extra", "valor")))  // combina parametros ya construidos
    .Build();

🔧 Extension Methods

param.AsOutput()
param.AsInputOutput()
param.WithSize(100)
param.WithPrecision(18, 2)
param.WithValue(value)

💡 Patrones Comunes

Parámetro Opcional

SqlParams.Param("Optional", value ?? null)

String Largo

SqlParams.String("Text", longText, SqlParams.Max)  // NVARCHAR(MAX)

Fecha sin Hora

SqlParams.Date("BirthDate", DateTime.Today)

Valor de Salida

var output = SqlParams.OutParam("Result", SqlDbType.Int);
await service.ExecuteAsync("sp_Proc", new[] { output });
int result = SqlParams.GetOutputValue<int>(output) ?? 0;

🚫 Valores Nulos y Valores por Defecto

Todos los métodos tipados (Int, String, Decimal, DateTime, DateTime2, Date, Bool, Guid, Binary) ya convierten null a DBNull.Value automáticamente — nunca revientan por un valor nulo. Además, aceptan un defaultValue opcional: si value es nulo, se usa defaultValue en su lugar; si ambos son nulos, se envía DBNull.Value como antes (sin romper el comportamiento previo).

// Sin default: value nulo -> DBNull
SqlParams.Int("Count", null);                          // DBNull

// Con default: value nulo -> usa el default en vez de DBNull
SqlParams.Int("Count", null, defaultValue: 0);          // 0
SqlParams.String("Status", null, defaultValue: "Pendiente"); // "Pendiente"
SqlParams.Bool("Active", null, defaultValue: true);     // true

Cuando quieres dejar explícito en el código que un valor es intencionalmente nulo (en vez de que value "termine siendo" nulo), usa SqlParams.DbNull:

SqlParams.DbNull("MiddleName", SqlDbType.NVarChar);            // NULL explícito
SqlParams.DbNull("Notes", SqlDbType.NVarChar, 200);            // NULL explícito, con tamaño
new SqlParameterBuilder().AddDbNull("Optional", SqlDbType.Int).Build();

⚠️ Errores Comunes

❌ Incorrecto ✅ Correcto
Param("Name", null) — tipo ambiguo, ADO.NET no puede inferirlo de un valor nulo DbNull("Name", SqlDbType.NVarChar) ✓
value == null ? 0 : value repetido en cada parámetro Int("Count", value, defaultValue: 0) ✓
String("Text", text) sin tamaño String("Text", text, SqlParams.Max) ✓
No verificar null en output GetOutputValue<int>(p) ?? 0 ✓

🚀 Inicio Rápido - 3 Pasos

1. Copia SqlParams.cs a tu proyecto

2. Agrega using

using DBSQLClient.Servicio.Parameter;

3. Usa en tu código

var parametros = SqlParams.AddParams(
    ("UserId", 123),
    ("Status", "Active")
);

var result = await service.ExecuteAsync("sp_GetUsers", parametros);

📚 Más Información

Ver ejemplos completos en: Ejemplos de Uso - SqlParams


📘 Guía Completa - Uso de SqlParameter

✅ Código Actualizado

El servicio ahora usa SqlParameter de Microsoft directamente. Más simple y estándar.


🎯 Formas de Crear Parámetros (de mejor a menos recomendada)

Opción 1: Constructor Simple (RECOMENDADA) ⭐⭐⭐⭐⭐

var parametros = new[]
{
    new SqlParameter("@pN1", 1),
    new SqlParameter("@pN2", 0),
    new SqlParameter("@pN3", 0)
};

var result = await service.ExecuteAsync("sp_MiProcedimiento", parametros);

Usando esta librería, el equivalente más corto es SqlParams.AddParams(("pN1", 1), ("pN2", 0), ("pN3", 0)) (ver "Referencia Rápida - SqlParams" más arriba). Esta sección sigue siendo útil para entender qué pasa "por debajo" o si prefieres SqlParameter sin ningún helper.

✅ Ventajas:

  • Más simple y directo
  • Menos líneas de código
  • Tipo se infiere automáticamente

Opción 2: Constructor con Tipo Explícito ⭐⭐⭐⭐

var parametros = new[]
{
    new SqlParameter("@pN1", SqlDbType.Int) { Value = 1 },
    new SqlParameter("@pN2", SqlDbType.Int) { Value = 0 },
    new SqlParameter("@pN3", SqlDbType.Int) { Value = 0 }
};

Cuándo usar:

  • Tipos complejos (DateTime, Decimal, etc.)
  • Para evitar ambigüedades
  • Para mayor control sobre el tipo SQL

Opción 3: Object Initializer ⭐⭐⭐

var parametros = new[]
{
    new SqlParameter { ParameterName = "@pN1", Value = 1, SqlDbType = SqlDbType.Int },
    new SqlParameter { ParameterName = "@pN2", Value = 0, SqlDbType = SqlDbType.Int },
    new SqlParameter { ParameterName = "@pN3", Value = 0, SqlDbType = SqlDbType.Int }
};

Opción 4: Inline (Para casos simples) ⭐⭐⭐⭐

var result = await service.ExecuteAsync("sp_MiProcedimiento", new[]
{
    new SqlParameter("@pN1", 1),
    new SqlParameter("@pN2", 0),
    new SqlParameter("@pN3", 0)
});

📊 Ejemplos por Tipo de Dato

Todos los tipos de esta sección tienen su equivalente más corto en SqlParams (SqlParams.Int, SqlParams.String, SqlParams.Decimal, SqlParams.DateTime/DateTime2/Date, SqlParams.Bool, SqlParams.Guid, SqlParams.Binary), incluyendo la conversión de null a DBNull.Value automática. Lo de abajo es útil si necesitas un SqlDbType que SqlParams no cubre todavía (ej: Xml, Time, Money) o si prefieres SqlParameter sin ningún helper.

Enteros

new SqlParameter("@Id", 123)
new SqlParameter("@Count", SqlDbType.Int) { Value = 100 }
new SqlParameter("@BigNumber", SqlDbType.BigInt) { Value = 999999999L }

Cadenas

new SqlParameter("@Name", "Juan Pérez")
new SqlParameter("@Email", SqlDbType.NVarChar, 100) { Value = "juan@email.com" }
new SqlParameter("@Description", SqlDbType.NVarChar, SqlParams.Max) { Value = longText } // SqlParams.Max = MAX

Fechas

new SqlParameter("@CreatedDate", SqlDbType.DateTime) { Value = DateTime.Now }
new SqlParameter("@UpdatedDate", SqlDbType.DateTime2) { Value = DateTime.UtcNow }
new SqlParameter("@OnlyDate", SqlDbType.Date) { Value = DateTime.Today }
new SqlParameter("@OnlyTime", SqlDbType.Time) { Value = DateTime.Now.TimeOfDay }

Decimales/Dinero

new SqlParameter("@Price", SqlDbType.Decimal) { Value = 99.99m, Precision = 18, Scale = 2 }
new SqlParameter("@Amount", SqlDbType.Money) { Value = 1500.50m }

Booleanos

new SqlParameter("@IsActive", SqlDbType.Bit) { Value = true }
new SqlParameter("@HasPermission", true) // Se convierte a bit automáticamente

Valores NULL

new SqlParameter("@OptionalField", SqlDbType.Int) { Value = DBNull.Value }

DateTime? birthDate = null; // ej: variable opcional que puede o no tener valor
new SqlParameter("@BirthDate", SqlDbType.DateTime) { Value = (object?)birthDate ?? DBNull.Value }

Binarios

byte[] fileData = File.ReadAllBytes("image.jpg");
new SqlParameter("@FileData", SqlDbType.VarBinary, SqlParams.Max) { Value = fileData }

Uniqueidentifier (GUID)

new SqlParameter("@UserId", SqlDbType.UniqueIdentifier) { Value = Guid.NewGuid() }

XML

string xmlData = "<root><item>value</item></root>";
new SqlParameter("@XmlData", SqlDbType.Xml) { Value = xmlData }

🔧 Parámetros de Salida (Output)

var parametros = new[]
{
    new SqlParameter("@InputId", 123),
    new SqlParameter("@OutputValue", SqlDbType.Int) { Direction = ParameterDirection.Output },
    new SqlParameter("@ReturnValue", SqlDbType.Int) { Direction = ParameterDirection.ReturnValue }
};

var result = await service.ExecuteAsync("sp_GetData", parametros);

// Leer valores de salida
int outputValue = (int)parametros[1].Value;
int returnValue = (int)parametros[2].Value;

Con SqlParams es SqlParams.OutParam("OutputValue", SqlDbType.Int) / SqlParams.ReturnParam(), y en vez de leer parametros[i].Value (que revienta si el SP no lo llenó) puedes usar result.GetOutputValue<int>("OutputValue"), que devuelve default en ese caso — ver la sección de parámetros de salida en DBSQLClient/README.md.


🔄 Parámetros Input/Output

var param = new SqlParameter("@Counter", SqlDbType.Int)
{
    Direction = ParameterDirection.InputOutput,
    Value = 10
};

var result = await service.ExecuteAsync("sp_IncrementCounter", new[] { param });

int newValue = (int)param.Value; // Valor actualizado por el SP

💡 Métodos Helper Recomendados

Ya existe en este proyecto: lo que sigue es el concepto general de por qué conviene un helper así (útil si estás integrando esta idea en OTRO proyecto que no tenga esta librería). Aquí mismo ya tienes DBSQLClient.Servicio.Parameter.SqlParams con esto y más (Max, DbNull, defaultValue, tipos específicos, etc.) — no lo reimplementes. Si aun así copias este ejemplo en un proyecto que también use el SqlParams real, no le pongas el mismo nombre: tu clase lo ocultaría en silencio (sin error de compilación) en cualquier archivo donde ambas queden en el mismo namespace o uno contenedor, por las reglas de precedencia de C# sobre using.

Helper Básico

public static class MiSqlHelper
{
    public static SqlParameter Param(string name, object? value)
    {
        return new SqlParameter(name, value ?? DBNull.Value);
    }

    public static SqlParameter Param(string name, object? value, SqlDbType type)
    {
        return new SqlParameter(name, type) { Value = value ?? DBNull.Value };
    }

    public static SqlParameter OutParam(string name, SqlDbType type)
    {
        return new SqlParameter(name, type) { Direction = ParameterDirection.Output };
    }
}

// USO
var parametros = new[]
{
    MiSqlHelper.Param("@Id", 123),
    MiSqlHelper.Param("@Name", "Juan"),
    MiSqlHelper.OutParam("@Result", SqlDbType.Int)
};

Helper con Fluent API

public static class SqlParameterExtensions
{
    public static SqlParameter AsOutput(this SqlParameter param)
    {
        param.Direction = ParameterDirection.Output;
        return param;
    }

    public static SqlParameter WithSize(this SqlParameter param, int size)
    {
        param.Size = size;
        return param;
    }

    public static SqlParameter WithPrecision(this SqlParameter param, byte precision, byte scale)
    {
        param.Precision = precision;
        param.Scale = scale;
        return param;
    }
}

// USO
var parametros = new[]
{
    new SqlParameter("@Name", SqlDbType.NVarChar).WithSize(100).WithValue("Juan"),
    new SqlParameter("@Price", SqlDbType.Decimal).WithPrecision(18, 2).WithValue(99.99m),
    new SqlParameter("@Result", SqlDbType.Int).AsOutput()
};

Más simple: para este caso concreto no hace falta ningún new SqlParameter — el SqlParameterBuilder ya incluido cubre size, precisión/escala y output con sus propios métodos:

var parametros = new SqlParameterBuilder()
    .AddString("Name", "Juan", 100)
    .AddDecimal("Price", 99.99m)     // precision=18, scale=2 por defecto
    .AddOutput("Result", SqlDbType.Int)
    .Build();

Y si ya tienes parámetros construidos por otro lado (ej: SqlParams.AddParams(...)), AddRange los combina en la misma cadena sin volver a escribirlos:

var parametros = new SqlParameterBuilder()
    .AddRange(SqlParams.AddParams(("Id", 1), ("Name", "Juan")))
    .AddOutput("Result", SqlDbType.Int)
    .Build();

📝 Ejemplos Completos de Uso

Ejemplo 1: Consulta Simple

var service = new SqlClientService(connectionString);

var parametros = new[]
{
    new SqlParameter("@UserId", 123)
};

var result = await service.QueryAsync(
    "SELECT * FROM Users WHERE Id = @UserId",
    parametros
);

var users = result.ToList<User>();

Ejemplo 2: Procedimiento con Múltiples Parámetros

var parametros = new[]
{
    new SqlParameter("@StartDate", SqlDbType.DateTime) { Value = DateTime.Now.AddDays(-30) },
    new SqlParameter("@EndDate", SqlDbType.DateTime) { Value = DateTime.Now },
    new SqlParameter("@Status", SqlDbType.NVarChar, 50) { Value = "Active" },
    new SqlParameter("@MinAmount", SqlDbType.Decimal) { Value = 100m }
};

var result = await service.ExecuteAsync("sp_GetSalesReport", parametros);

Ejemplo 3: Con Parámetros de Salida

var parametros = new[]
{
    new SqlParameter("@UserId", 123),
    new SqlParameter("@TotalOrders", SqlDbType.Int) { Direction = ParameterDirection.Output },
    new SqlParameter("@TotalAmount", SqlDbType.Decimal) { Direction = ParameterDirection.Output, Precision = 18, Scale = 2 }
};

var result = await service.ExecuteAsync("sp_GetUserStatistics", parametros);

// Leer valores de salida
int totalOrders = (int)parametros[1].Value;
decimal totalAmount = (decimal)parametros[2].Value;

Console.WriteLine($"Órdenes: {totalOrders}, Total: ${totalAmount}");

Ejemplo 4: Con Valores Nullables

int? optionalId = null;
string? optionalName = null;

var parametros = new[]
{
    new SqlParameter("@Id", (object?)optionalId ?? DBNull.Value),
    new SqlParameter("@Name", (object?)optionalName ?? DBNull.Value)
};

var result = await service.QueryAsync("SELECT * FROM Users WHERE (@Id IS NULL OR Id = @Id)", parametros);

Ejemplo 5: Inline para Casos Simples

// Sin variable intermedia
var result = await service.ExecuteAsync("sp_DeleteUser", new[]
{
    new SqlParameter("@UserId", 123)
});

if (result.HasRows)
{
    Console.WriteLine("Usuario eliminado");
}

⚠️ Errores Comunes y Soluciones

Error 1: Tipo incorrecto

// ❌ INCORRECTO
new SqlParameter("@Price", DbType.Decimal) // DbType en lugar de SqlDbType

// ✅ CORRECTO
new SqlParameter("@Price", SqlDbType.Decimal)

Error 2: Tamaño de string

// ❌ PUEDE TRUNCAR
new SqlParameter("@LongText", longString) // Sin especificar tamaño

// ✅ CORRECTO
new SqlParameter("@LongText", SqlDbType.NVarChar, SqlParams.Max) { Value = longString } // SqlParams.Max = MAX

Error 3: Valores NULL

// ❌ INCORRECTO
new SqlParameter("@OptionalField", null) // Puede causar error

// 😕 CORRECTO, PERO VERBOSO — repetir esto por cada parámetro opcional cansa
new SqlParameter("@OptionalField", (object?)value ?? DBNull.Value)

// ✅ MÁS SIMPLE — SqlParams ya hace esta conversión por ti
SqlParams.Param("OptionalField", value)

Este es el punto de SqlParams: te evita escribir (object?)value ?? DBNull.Value a mano en cada parámetro. Param, Int, String, Decimal, etc. ya convierten null a DBNull.Value automáticamente — para eso existe la librería.

Error 4: Olvidar @ en el nombre

// ✅ AMBOS SON VÁLIDOS con este servicio
new SqlParameter("@UserId", 123)  // Con @
new SqlParameter("UserId", 123)   // Sin @

SqlParameter de Microsoft no agrega el @ por sí sola — si ejecutaras este parámetro con SqlCommand puro y olvidaras el @, fallaría en tiempo de ejecución (el nombre no coincidiría con @UserId en tu SQL o procedimiento almacenado). Este servicio lo maneja internamente: tanto SqlParams.Param/Int/String/etc. como SqlCommandExecutor (el punto por el que pasa toda ejecución, incluyendo SqlParameter armados a mano) normalizan el nombre agregando el @ si falta, antes de mandarlo a SQL Server. No necesitas acordarte de ponerlo.


🎯 Mejores Prácticas

  1. Usa parámetros siempre - Previene SQL Injection
  2. Especifica tipos para decimales y fechas - Evita problemas de conversión
  3. Usa SqlParams.Max (-1) para NVARCHAR(MAX) - Para textos largos, en vez del número mágico -1
  4. Maneja valores NULL correctamente - Usa DBNull.Value
  5. Nombra parámetros con @ - Es la convención estándar
  6. Reutiliza helpers - Crea métodos helper para casos comunes
  7. Valida tamaños - Especifica Size para strings

📚 Referencia Rápida de Tipos

Tipo C# SqlDbType Ejemplo
int Int new SqlParameter("@Id", 123)
long BigInt new SqlParameter("@BigId", 999999L)
string NVarChar new SqlParameter("@Name", "Juan")
decimal Decimal new SqlParameter("@Price", 99.99m)
DateTime DateTime / DateTime2 new SqlParameter("@Date", DateTime.Now)
bool Bit new SqlParameter("@IsActive", true)
Guid UniqueIdentifier new SqlParameter("@Guid", Guid.NewGuid())
byte[] VarBinary new SqlParameter("@Data", byteArray)

✅ Resumen

Para el 90% de los casos:

var parametros = new[]
{
    new SqlParameter("@Param1", valor1),
    new SqlParameter("@Param2", valor2)
};

var result = await service.ExecuteAsync("sp_MiProcedimiento", parametros);

Para casos complejos, crea helpers personalizados según las necesidades de tu proyecto.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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
0.1.1 159 7/9/2026
0.1.0 116 7/9/2026