Dinaup - Base de Conocimientos Help

Dinaup.Database

Dinaup.Database es una librería .NET (compatible con .NET Framework y .NET Core) que proporciona una interfaz simplificada para trabajar con PostgreSQL. Sus objetivos principales son:

  • Facilitar la conexión a bases de datos PostgreSQL, soportando SSL y cadenas de conexión en formatos estándar.

  • Realizar lecturas sencillas de datos (listas, diccionarios, modelos) sin tener que lidiar directamente con DataReaders.

  • Ofrecer métodos de inserción, actualización y "upsert" (inserción o actualización según la existencia de registros).

  • Soportar la lectura por lotes de grandes cantidades de datos.

  • Integrarse con clases modelo a través de interfaces simples para mapear resultados a objetos de negocio.

  • Segura Multithreading.

  • Reutilización de conexión.

Instalación

Desde NuGet:

dotnet add package Dinaup.Database

Github Dinaup.Database.

Clase Principal: PGClient

La clase PGClient proporciona métodos para:

  • Conexión y reconexión a PostgreSQL (con SSL si se requiere).

  • Ejecución de sentencias SQL.

  • Lectura de resultados (listas, diccionarios, modelos).

  • Inserción, actualización, y operaciones de upsert.

  • Lectura de datos en lotes.

Propiedades Principales

  • IsConnected (bool): Indica si la conexión está abierta.

  • Host, Port, UserName, Password, DatabaseName: Parámetros de conexión.

  • UseSSL: Indica si se usa SSL.

  • Description: Descripción opcional de la conexión.

  • TablesAndColumns: Diccionario opcional de tablas a columnas.

Establecer Conexión

Conexión con parámetros separados:

var client = new PGClient(); client.Connect("localhost", 5432, "myuser", "mypassword", "mydatabase"); if (client.IsConnected) { Console.WriteLine("Conexión establecida correctamente."); }

Con SSL (cadena estilo URL):

string connectionString = "postgres://user:password@host:port/dbname?sslmode=require"; client.ConnectWithSSL(connectionString);

Con SSL (parámetros separados):

client.ConnectWithSSL("host", 5432, "user", "password", "databaseName");

Lectura de Datos

  • ReadValue(string SQL): Retorna un único valor (cadena).

  • ReadList(string SQL): Retorna una lista de cadenas (asumiendo una sola columna).

  • ReadDictionary(string SQL): Retorna un Dictionary<string, string> a partir de pares clave-valor.

  • ReadDictionaryList(string SQL): Retorna una lista de diccionarios (una fila por diccionario).

  • ReadObjectList<T>(string SQL) (donde T: BaseModelConverter): Retorna una lista de objetos T mapeados desde la BD.

Ejemplos:

// Leer un valor único var countStr = client.ReadValue("SELECT COUNT(*) FROM test_table;"); int totalRegistros = int.Parse(countStr); // Leer una lista (una columna) var nombres = client.ReadList("SELECT name FROM test_table ORDER BY id;"); foreach (var nombre in nombres) { Console.WriteLine(nombre); } // Leer una lista de diccionarios var registros = client.ReadDictionaryList("SELECT id, name, value FROM test_table WHERE id < 10;"); foreach (var reg in registros) { Console.WriteLine($"ID: {reg["id"]}, Name: {reg["name"]}, Value: {reg["value"]}"); }

Lectura de Modelos

Si se dispone de clases que heredan de BaseModelConverter, puede mapearse directamente:

public class TestModel : BaseModelConverter { public int Id { get; set; } public string Name { get; set; } public int Value { get; set; } public override void FromDic(Dictionary<string, string> dic) { this.Id = dic.GetM("id").INT(0); this.Name = dic.GetM("name"); this.Value = dic.GetM("value").INT(0); } public override string Table => "test_table"; public override string[] Fields => new[] { "id", "name", "value" }; public override string LastModifiedFieldDatetimeUTC => ""; // No usado en este ejemplo } // Ejemplo de uso var modelos = client.ReadObjectList<TestModel>("SELECT * FROM test_table ORDER BY id;"); foreach (var m in modelos) { Console.WriteLine($"{m.Id} - {m.Name} - {m.Value}"); }

Inserción, Actualización y Upsert

  • InsertRecord(tableName, record): Inserta un diccionario como registro.

  • InsertRecords(tableName, records): Inserta múltiples registros a la vez.

  • UpdateRecord(tableName, dataDict, idField, idValue): Actualiza el registro cuyo campo idField coincide con idValue.

  • InsertOrIgnoreRecord(tableName, dataDict): Inserta el registro si no hay conflicto.

  • InsertOrUpdateRecord(tableName, dataDict, idField): Inserta o actualiza según exista el registro.

  • InsertOrUpdateRecords(tableName, dataDicts, idField): Inserta o actualiza múltiples registros.

Ejemplo: Insertar un registro

var nuevoRegistro = new Dictionary<string, string> { {"name", "NuevoNombre"}, {"value", "123"} }; int rowsAffected = client.InsertRecord("test_table", nuevoRegistro); Console.WriteLine("Filas insertadas: " + rowsAffected);

Ejemplo: Actualizar un registro

var datosActualizar = new Dictionary<string, string> { {"value", "999"} }; int filasActualizadas = client.UpdateRecord("test_table", datosActualizar, "id", "1"); Console.WriteLine("Filas actualizadas: " + filasActualizadas);

Ejemplo: Upsert (insertar o actualizar)

var registroUpsert = new Dictionary<string, string> { {"id", "100"}, {"name", "Registro100"}, {"value", "1000"} }; int affected = client.InsertOrUpdateRecord("test_table", registroUpsert, "id"); Console.WriteLine("Filas modificadas: " + affected);

Lectura en Lotes (Batch Reading)

Para grandes cantidades de datos:

  • BatchReadDictionaries(description, countSQL, dataSQL, batchSize): Iterador que produce lotes de diccionarios.

  • BatchReadObjects<T>(description, countSQL, dataSQL, batchSize): Igual que el anterior pero para objetos de tipo T.

Ejemplo:

var batches = client.BatchReadDictionaries( "Lectura en lotes", "SELECT COUNT(*) FROM test_table", "SELECT id, name, value FROM test_table ORDER BY id", 1000 ); foreach (var batch in batches) { Console.WriteLine("Lote de " + batch.Count + " registros"); foreach (var reg in batch) { Console.WriteLine($"{reg["id"]} - {reg["name"]} - {reg["value"]}"); } }

Clonar Conexiones

DuplicateConnection() crea una nueva instancia PGClient con la misma configuración y abre la conexión.

var repoClonado = client.DuplicateConnection(); if (repoClonado.IsConnected) { Console.WriteLine("Conexión clonada y funcionando."); }

Manejo de Errores

Se pueden capturar excepciones con try...catch.

try { client.ExecuteNonQuery("INSERT INTO test_table (name, value) VALUES ('Test', 1)"); } catch (Exception ex) { Console.WriteLine("Error en la inserción: " + ex.Message); }

Liberación de Recursos

PGClient implementa IDisposable, por lo que es recomendable usar using:

using (var client = new PGClient()) { client.Connect("localhost", 5432, "user", "pass", "db"); // ... Operaciones ... } // Aquí se libera la conexión automáticamente

Ejemplos Completos

Ejemplo 1: Leer todos los registros (c#)

var client = new PGClient(); client.Connect("localhost", 5432, "user", "password", "mydb"); var listaNombres = client.ReadList("SELECT name FROM test_table ORDER BY id;"); foreach (var nombre in listaNombres) { Console.WriteLine(nombre); }

Ejemplo 2: Insertar y luego leer modelos (c#)

var client = new PGClient(); client.ConnectWithSSL("postgres://user:pass@host:port/mydb?sslmode=require"); // Insertar un registro var nuevo = new Dictionary<string, string> { {"name", "NuevoRegistro"}, {"value", "100"} }; client.InsertRecord("test_table", nuevo); // Leer como objetos var objetos = client.ReadObjectList<TestModel>("SELECT * FROM test_table WHERE name='NuevoRegistro'"); foreach (var obj in objetos) { Console.WriteLine($"{obj.Id}: {obj.Name} - {obj.Value}"); }

Ejemplo 3: Actualizar o Ignorar si existe (c#)

var client = new PGClient(); client.Connect("localhost", 5432, "user", "password", "mydb"); var registro = new Dictionary<string, string> { {"id", "1"}, {"name", "Test1"}, {"value", "999"} }; // InsertOrUpdate int afectadas = client.InsertOrUpdateRecord("test_table", registro, "id"); Console.WriteLine("Filas afectadas: " + afectadas);

Ayuda

Para obtener ayuda y discutir sobre la librería, únete a nuestra comunidad en Discord.

El código fuente, ejemplos adicionales y las últimas actualizaciones están disponibles en nuestro repositorio oficial de GitHub: Dinaup.Database.

Last modified: 04 February 2025