imagen en ola para slider
Asegura tu éxito con nuestras soluciones tecnológicas - Adfines (Impulsamos tu éxito) Asegura tu éxito con nuestras soluciones tecnológicas - Adfines (Impulsamos tu éxito)

Asegura tu éxito con nuestras soluciones tecnológicas

En Adfines, te ofrecemos diversas soluciones tecnológicas que te permitirán optimizar tu negocio. Descubre nuestras herramientas innovadoras y seguras para asegurar un futuro exitoso.

Soluciones tecnológicas a medida para tus necesidades - Adfines (Impulsamos tu éxito) Soluciones tecnológicas a medida para tus necesidades - Adfines (Impulsamos tu éxito)

Soluciones tecnológicas personalizadas para tus necesidades

Obtén la solución tecnológica que se adapte a tus necesidades. En Adfines, te ofrecemos opciones flexibles y herramientas personalizadas. Nuestros expertos te guiarán en el proceso para que consigas la mejor tecnología para tu proyecto.

Forma parte de una comunidad innovadora y comprometida - Adfines (Impulsamos tu éxito) Forma parte de una comunidad innovadora y comprometida - Adfines (Impulsamos tu éxito)

Forma parte de una comunidad innovadora y dedicada

Al unirte a Adfines, te integrarás a una comunidad de clientes innovadores y colaborativos. Participa en actividades exclusivas, eventos y programas que fortalecen las conexiones entre nuestros miembros.

Haz crecer tu negocio como cliente - Adfines (Impulsamos tu éxito) Haz crecer tu negocio como cliente - Adfines (Impulsamos tu éxito)

Haz crecer tu negocio como cliente

Únete a Adfines y descubre las soluciones tecnológicas exclusivas que tenemos para ti. Obtén innovación y asegura el éxito de tu negocio como cliente de nuestra plataforma.

Accede a soluciones tecnológicas integrales en un solo lugar - Adfines (Impulsamos tu éxito) Accede a soluciones tecnológicas integrales en un solo lugar - Adfines (Impulsamos tu éxito)

Accede a soluciones tecnológicas integrales en un solo lugar

En Adfines, te ofrecemos una amplia gama de soluciones tecnológicas en un solo lugar. Desde herramientas de desarrollo hasta servicios de soporte y consultoría, simplifica tus procesos tecnológicos con nosotros.

imagen en ola inferior para slider
Logo de adfines en menú

Net.Ganesha 2.0.7

Adfines - Contigo en lo que tu Sueñes

Es un paquete NuGet diseñado para la plataforma .NET que simplifica la interacción con bases de datos y APIs. Proporciona herramientas para gestionar conexiones y transacciones, ejecutar consultas SQL de manera segura, y manejar errores de forma centralizada. Es compatible con múltiples bases de datos como PostgreSQL, SQL Server, y MySQL, y está optimizado para su uso en aplicaciones modernas de .NET6 en adelante. Además, su flexibilidad permite adaptarse a diversas configuraciones y entornos, incluidos los basados en la nube.

Tiempo de aprobación: 2 Horas Desde que se comience a experimentar con la libreria

Más información
Simplificación del manejo de bases de datos y APIs
  • Adfines.Net.Ganesha proporciona abstracciones que simplifican la conexión, transacción, y consulta de bases de datos, así como la interacción con APIs externas. Esto reduce la complejidad del código y minimiza el riesgo de errores comunes.
Centralización y robustez en la gestión de errores
  • Ofrece mecanismos centralizados para el manejo de errores y advertencias, lo que mejora la robustez del código y facilita el diagnóstico y solución de problemas. Esta centralización permite mantener un control más riguroso sobre cómo se gestionan las excepciones en toda la aplicación.
Compatibilidad y flexibilidad
  • Es compatible con múltiples bases de datos populares y versiones modernas de .NET6 en adelante, lo que brinda flexibilidad en el desarrollo y despliegue de aplicaciones. Además, está preparado para integrarse en entornos de nube, lo que facilita la creación de aplicaciones escalables y distribuidas.

Adfines.Net.Ganesha - Gestor Multi-Base de Datos para .NET

📋 Descripción

Adfines.Net.Ganesha es un paquete NuGet diseñado para simplificar y optimizar la gestión de múltiples tipos de bases de datos en aplicaciones .NET 6+. Soporta MySQL, SQL Server, PostgreSQL y Oracle con una API unificada.

🚀 Características Principales

📦 Instalación

dotnet add package Adfines.Net.Ganesha

🔐 Encriptación de Contraseñas

// Para encriptar contraseñas (cuando AfCrypt = true)
string passwordEncriptado = Adfines.Net.Ganesha.Xtra.Password.E("Hola mundo");
Console.WriteLine(passwordEncriptado);
// El valor retornado es el que se debe colocar en Password cuando AfCrypt es true

🗄️ BASES DE DATOS SOPORTADAS

MySQL / MariaDB

using Adfines.Net.Ganesha.Utils;

var mysql = new MySql(new Initializer()
{
    AfCrypt = true,
    Bdd = "onepiece",
    User = "root",
    Password = "SbBW2UXX83XHhG9Wr/tVQ9beTQ/W59hYTf2FMqL/K4A=",
    Ip = "localhost",
    Port = 3306,
    SslMode = "2"
});

SQL Server

var sqlServer = new SqlServer(new Initializer()
{
    AfCrypt = true,
    Bdd = "prod",
    User = "sa",
    Password = "SbBW2UXX83XHhG9Wr/tVQ13gAq5/rlkTkE22fgB/Nlw=",
    IntegratedSecurity = false,
    TrustCertificate = true
});

PostgreSQL

var postgresql = new PostgreSql(new Initializer()
{
    AfCrypt = true,
    Bdd = "postgres", 
    User = "odoo",
    Password = "SbBW2UXX83XHhG9Wr/tVQzBYlM7x4OaeU8ohdoTdWSg=",
    TrustCertificate = true
});

Oracle

var oracle = new Oracle(new Initializer()
{
    AfCrypt = true,
    Bdd = "XE",
    User = "system", 
    Password = "SbBW2UXX83XHhG9Wr/tVQzzsIpm04BOM7m2vZqvEAAk=",
    Protocol = "1"  // 1: TCP, 2: TCPS, 3: IPC, 4: NMP, 5: SDP
});

🔧 CONFIGURACIÓN DE CONEXIÓN

Parámetros Comunes

ParámetroTipoRequeridoDescripción
AfCryptboolHabilita cifrado de credenciales
BddstringNombre de la base de datos
UserstringUsuario
PasswordstringContraseña (cifrada/plana)
IpstringIP/hostname (default: localhost)
PortintPuerto
ErrorstringTabla para logs de errores
WarningstringTabla para logs de advertencias
ConnectionTimeOutintTimeout conexión (segundos)
QueryTimeOutintTimeout consulta (segundos)
PoolSizeintTamaño pool conexiones

Parámetros Específicos

Base de DatosParámetros Específicos
MySQLSslMode: "1"-"5"
SQL ServerIntegratedSecurityTrustCertificate
PostgreSQLTrustCertificate
OracleProtocol: "1"-"5"

🛠️ FORMAS DE INICIALIZACIÓN

Forma 1: Configuración Directa

var msql = new MySql(new Initializer()
{
    AfCrypt = true,
    Bdd = "onepiece",
    User = "root",
    Password = "SbBW2UXX83XHhG9Wr/tVQ9beTQ/W59hYTf2FMqL/K4A="
});

Forma 2: Desde appsettings.json

var msql = new MySql("EjemploMysql");

appsettings.json:

{
  "AdfinesGaneshaNet": {
    "EjemploMysql": {
      "AfCrypt": true,
      "Bdd": "onepiece",
      "User": "root",
      "Password": "SbBW2UXX83XHhG9Wr/tVQ9beTQ/W59hYTf2FMqL/K4A="
    }
  }
}

Forma 3: Con Parámetros Directos

var msql = new MySql(new Initializer(
    afCrypt: true,
    bdd: "onepiece", 
    user: "root",
    password: "SbBW2UXX83XHhG9Wr/tVQ9beTQ/W59hYTf2FMqL/K4A=",
    ip: "localhost",
    port: 3306
));

Forma 4: Desde Archivo Externo

// JSON
var msql = new MySql(new Initializer("/ruta", "config", "json"));

// CSV  
var msql = new MySql(new Initializer("/ruta", "config", "csv"));

💻 OPERACIONES COMUNES A TODAS LAS BASES DE DATOS

Verificación de Conexión

if (mysql.Success) 
{
    Console.WriteLine("Conexión exitosa a la base de datos");
}

SELECT

var resultado = mysql.Select(
    "SELECT * FROM usuarios WHERE edad > @edad", 
    new() { ["edad"] = 18 },
    "Error al obtener usuarios"
);

INSERT

var insercion = mysql.Insert(
    "usuarios (nombre, email) VALUES (@nombre, @email)",
    new() { ["nombre"] = "Juan", ["email"] = "juan@ejemplo.com" },
    "Error al insertar usuario"
);

UPDATE

var actualizacion = mysql.Update(
    "usuarios SET activo = 1 WHERE id = @id",
    new() { ["id"] = 1 },
    "Error al actualizar usuario"
);

DELETE

var eliminacion = mysql.Delete(
    "usuarios WHERE id = @id", 
    new() { ["id"] = 1 },
    "Error al eliminar usuario"
);

RAW (Consultas Crudas)

var raw = mysql.Raw(@"
    INSERT INTO log (accion) VALUES ('inicio');
    UPDATE contador SET valor = valor + 1;
", "Error en consultas raw");

INSERTED (Inserción con Retorno de ID)

var inserted = mysql.Inserted(
    "usuarios (nombre) VALUES (@nombre)",
    new() { ["nombre"] = "Maria" },
    "Error al insertar"
);

📊 TABLAS DE ESTRUCTURAS DE RETORNO

Entity.Read (SELECT)

PropiedadTipoDescripción
Err.Flagbooltrue si hubo error en la consulta
Err.IdlongID del registro de error en la tabla de logs
First.DicDictionary<string, object?>Primer registro como Dictionary
First.ObjJObjectPrimer registro como JObject (Newtonsoft)
Info.ListIList<Dictionary<string, object?>>Todos los registros como lista de Dictionary
Info.ArrayJArrayTodos los registros como JArray (Newtonsoft)
Info.CountintNúmero total de registros

Entity.Insert / Update / Delete / Raw

PropiedadTipoDescripción
Okbooltrue si la operación fue exitosa
ErrlongID del registro de error (0 si no hubo error o no se pudo guardar)

Entity.Inserted

PropiedadTipoDescripción
IdlongID del registro insertado (si la tabla tiene identity/autoincrement)
Error.Flagbooltrue si hubo error en la inserción
Error.IdlongID del registro de error en la tabla de logs

Entity.Err / Entity.Warning

PropiedadTipoDescripción
FlagboolNota: Comportamiento invertido. true = éxito, false = error al guardar
IdlongID del registro creado en la tabla de logs

Entity.Props

PropiedadTipoDescripción
ListIList<string>Lista de esquemas o tablas
ColumnList<Column>Lista de columnas con metadatos
Err.Flagbooltrue si hubo error
Err.IdlongID del registro de error

Estructura Column (Metadatos de Columnas)

PropiedadTipoDescripción
NamestringNombre de la columna
Itemint?Posición/orden de la columna
TypestringTipo de dato de la columna
Lengthint?Longitud máxima de la columna
Scaleint?Escala (para tipos decimales)
Presicionint?Precisión (para tipos numéricos)
Nullbool?true si permite valores NULL
Incrementbool?true si es auto-incremental
DefaultValuestringValor por defecto de la columna
CollationstringCollation/ordenamiento
DescriptionstringDescripción de la columna
DefinitionstringDefinición completa
Persistedbool?true si es persistente
SequenceNamestringNombre de la secuencia (si aplica)
SequenceSchemastringEsquema de la secuencia (si aplica)

🔍 OPERACIONES PROPS (METADATOS)

MySQL (Sin Esquemas)

// Listar todas las tablas
var tablas = mysql.Props();
foreach (var tabla in tablas.List)
{
    Console.WriteLine($"Tabla: {tabla}");
}

// Obtener columnas de una tabla
var columnas = mysql.Props("usuarios");
foreach (var columna in columnas.Column)
{
    Console.WriteLine($"Columna: {columna.Name}, Tipo: {columna.Type}, Nulo: {columna.Null}");
}

SQL Server, PostgreSQL, Oracle (Con Esquemas)

// Listar todos los esquemas
var esquemas = sqlServer.Props();
foreach (var esquema in esquemas.List)
{
    Console.WriteLine($"Esquema: {esquema}");
}

// Listar tablas de un esquema  
var tablas = sqlServer.Props("dbo");
foreach (var tabla in tablas.List)
{
    Console.WriteLine($"Tabla: {tabla}");
}

// Obtener columnas de una tabla en un esquema
var columnas = sqlServer.Props("dbo", "usuarios");
foreach (var columna in columnas.Column)
{
    Console.WriteLine($"Columna: {columna.Name}, Tipo: {columna.Type}");
}

🗃️ CONFIGURACIÓN DE TABLAS DE LOG

Tabla de Errores (error_table)

CREATE TABLE error_table(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    creacion DATETIME NOT NULL,
    valor TEXT NOT NULL,
    codigo TEXT NOT NULL,
    descripcion TEXT NOT NULL
);

Tabla de Advertencias (warn_table)

CREATE TABLE warn_table(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    creacion DATETIME NOT NULL,
    valor TEXT NOT NULL,
    codigo TEXT NOT NULL,
    descripcion TEXT NOT NULL
);

🐛 MANEJO DE ERRORES Y ADVERTENCIAS

Log Automático

Los errores en consultas SELECT, INSERT, UPDATE, DELETE se registran automáticamente cuando se proporciona el parámetro de descripción de error.

Log Manual

try
{
    // Operación riesgosa
    var numero = "hola mundo";
    var i = int.Parse(numero);
}
catch (Exception e)
{
    // Registrar error
    var error = mysql.Error(e, "Dio error al tratar de convertir un numero: " + numero);
    
    // Registrar advertencia  
    var warning = mysql.Warning(e, "No se pudo convertir el numero " + numero);
    
    // NOTA: Flag se invierte para consultas de error puras
    if (!error.Flag) // true = éxito, false = error al guardar
    {
        Console.WriteLine("Hubo un error al tratar guardar el error");
    }
    else
    {
        Console.WriteLine("id del error: " + error.Id);
    }
}

🔍 EJEMPLOS COMPLETOS

Ejemplo 1: Operación Completa con Manejo de Errores

var mysql = new MySql(new Initializer() { 
    AfCrypt = true,
    Bdd = "onepiece",
    User = "root",
    Password = "SbBW2UXX83XHhG9Wr/tVQ9beTQ/W59hYTf2FMqL/K4A=",
    Error = "error_table",
    Warning = "warn_table"
});

if (mysql.Success) 
{
    Console.WriteLine("Conexión exitosa a la base de datos");
    
    // SELECT con parámetros
    var usuarios = mysql.Select(
        "SELECT * FROM luffy WHERE id > @id AND nombre LIKE @nombre", 
        new() 
        {
            ["id"] = 0,
            ["nombre"] = "%lu%"
        },
        "Problemas al querer listar luffy"
    );
    
    if (usuarios.Err.Flag)
    {
        if (usuarios.Err.Id < 1)
        {
            Console.WriteLine("No se pudo guardar el error en la base de datos");
        }
        else
        {
            Console.WriteLine("Hubo un error. ID del error: " + usuarios.Err.Id);
        }
    }
    else
    {
        // Procesar resultados en diferentes formatos
        Dictionary<string, object?> primerRegistro = usuarios.First.Dic;
        JObject primerRegistroJson = usuarios.First.Obj;
        IList<Dictionary<string, object?>> todosRegistros = usuarios.Info.List;
        JArray todosRegistrosJson = usuarios.Info.Array;
        int totalRegistros = usuarios.Info.Count;
        
        Console.WriteLine($"Total de registros: {totalRegistros}");
        
        // Advertencia condicional
        if (totalRegistros > 100)
        {
            mysql.Warning(new ArgumentException(), "La tabla ya tiene mas de 100 registros");
        }
    }
}

Ejemplo 2: Inserción con Retorno de ID

var inserted = mysql.Inserted(
    @"luffy (nombre, creacion, edad, poder, activo) VALUES (@nombre, @creacion, @edad, @poder, @activo)",
    new()
    {
        ["nombre"] = "luis 3",
        ["creacion"] = "TIMESTAMP()",
        ["edad"] = 89,
        ["poder"] = 55.5,
        ["activo"] = null
    },
    "Hubo un error al querer insertar en luffy"
);

if (inserted.Error.Flag)
{
    if (inserted.Error.Id < 1)
    {
        Console.WriteLine("No se pudo insertar el id del error o no se pudo recuperar el id de la tabla error");
    }
    else
    {
        Console.WriteLine("id del error al insertar: " + inserted.Error.Id);
    }
}
else
{
    Console.WriteLine($"Inserción exitosa. ID: {inserted.Id}");
}

Ejemplo 3: Inserción Múltiple

var insercionMultiple = mysql.Inserts("luffy",
[
    new()
    {
        ["nombre"] = "luis 4",
        ["creacion"] = "TIMESTAMP()",
        ["edad"] = 89,
        ["poder"] = 55.5,
        ["activo"] = null
    },
    new()
    {
        ["nombre"] = "luis 5", 
        ["creacion"] = "TIMESTAMP()",
        ["edad"] = 90,
        ["poder"] = 60.0,
        ["activo"] = 1
    }
], "Hubo un error al querer insertar en luffy");

if (!insercionMultiple.Ok)
{
    Console.WriteLine("Error en inserción múltiple. ID error: " + insercionMultiple.Err);
}

Ejemplo 4: Consultas RAW Múltiples

var activoLuffyRaw = 1;
var consultasRaw = mysql.Raw(@"
    INSERT INTO luffy (nombre, creacion, edad, poder) VALUES ('luis 55', TIMESTAMP(), 80, 22.2);
    UPDATE luffy SET activo = {activoLuffyRaw} WHERE nombre = 'luis 55';
    DELETE FROM luffy WHERE edad > 100;
", "Hubo un error al ejecutar una consulta cruda");

if (!consultasRaw.Ok)
{
    Console.WriteLine("Error en consultas RAW. ID error: " + consultasRaw.Err);
}

❓ PREGUNTAS FRECUENTES (FAQ)

¿Cómo elijo entre las diferentes bases de datos?

Use la clase correspondiente:

¿Es obligatorio el WHERE en UPDATE/DELETE?

, por razones de seguridad todas las bases de datos requieren WHERE en UPDATE/DELETE.

¿Qué significa el comportamiento invertido de Flag en Entity.Err?

En consultas de error puras (Error() y Warning()), Flag = true significa éxito y Flag = false significa error. Esto es diferente a otras operaciones.

¿Cómo obtengo el ID del registro insertado?

Use Inserted() en lugar de Insert() para obtener el ID del registro insertado.

¿Puedo ejecutar múltiples consultas en una sola operación?

Sí, use Raw() con consultas separadas por punto y coma.

📝 NOTAS IMPORTANTES


Ver Paquete Nuget