Introducción al objeto DataReader

El objeto DataReader es un lector de datos que proporciona acceso de solo lectura y solo avance. Está diseñado para leer datos desde los resultados de una consulta, una fila a la vez, manteniendo la conexión abierta durante todo el proceso.

Cada proveedor de datos de .NET Framework define su propia clase DataReader:

Proveedor de datos .NET Clase DataReader
SQL Server .NET Framework Data Provider SqlDataReader
OLE DB .NET Framework Data Provider OleDbDataReader
ODBC .NET Framework Data Provider OdbcDataReader

Propiedades comunes de DataReader:

Propiedad Descripción
FieldCount Obtiene el número de columnas en la fila actual.
HasRows Indica si el resultado contiene filas pendientes de lectura (tipo bool).

Métodos comunes de DataReader:

Método Descripción
Read() Avanza el lector a la siguiente fila. Devuelve true si hay una fila disponible, false en caso contrario.
Close() Cierra el objeto DataReader.
GetName(index) Obtiene el nombre de la columna en la posición index.

A continuación, se muestra un ejemplo práctico del uso de DataReader para leer datos de una tabla de administradores.

using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = "server=.;database=3CDB;Integrated Security=true";
        
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();
            
            if (conn.State == System.Data.ConnectionState.Open)
            {
                string query = "SELECT ID, LoginId, LoginPwd, Name FROM Admins";
                
                using (SqlCommand cmd = new SqlCommand(query, conn))
                using (SqlDataReader lector = cmd.ExecuteReader())
                {
                    Console.WriteLine("ID\tUsuario\tContraseña\tNombre");
                    Console.WriteLine("------------------------------------");
                    
                    while (lector.Read())
                    {
                        // Acceso por nombre de columna (más flexible)
                        string id = lector["ID"].ToString();
                        string usuario = lector["LoginId"].ToString();
                        string contrasena = lector["LoginPwd"].ToString();
                        string nombre = lector["Name"].ToString();
                        
                        Console.WriteLine($"{id}\t{usuario}\t{contrasena}\t{nombre}");
                    }
                } // El lector se cierra automáticamente al salir del bloque using
            }
        } // La conexión se cierra automáticamente al salir del bloque using
    }
}

El ejemplo anterior muestra cómo:

  • Crear y abrir una conexión.
  • Crear un comando SQL con la instrucción SELECT.
  • Ejecutar el comando con ExecuteReader() para obtener un SqlDataReader.
  • Usar un bucle while con Read() para recorrer todas las filas.
  • Acceder a los valores de cada columna mediante el indizador por nombre de columna (recomendado) y convertir a string con ToString().
  • Cerrar el lector y la conexión (aquí mediante using, que llama automáticamente a Dispose).

Uso de ExecuteScalar con funciones de agregación

Cuando se ejecutan consultas que devuelven un único valor (por ejemplo, COUNT, SUM, AVG), se debe utilizar el método ExecuteScalar() del objeto Command. Este método devuelve un object que luego se convierte al tipo deseado.

using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = "server=.;database=3CDB;Integrated Security=true";
        
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();
            
            if (conn.State == System.Data.ConnectionState.Open)
            {
                // Contar productos
                string sqlCount = "SELECT COUNT(*) FROM Products";
                using (SqlCommand cmdCount = new SqlCommand(sqlCount, conn))
                {
                    string totalProductos = cmdCount.ExecuteScalar().ToString();
                }
                
                // Suma total de stock * precio
                string sqlSuma = "SELECT SUM(stock * price) FROM Products";
                using (SqlCommand cmdSuma = new SqlCommand(sqlSuma, conn))
                {
                    string montoTotal = cmdSuma.ExecuteScalar().ToString();
                }
                
                // Promedio de precio
                string sqlPromedio = "SELECT AVG(price) FROM Products";
                using (SqlCommand cmdPromedio = new SqlCommand(sqlPromedio, conn))
                {
                    string precioPromedio = cmdPromedio.ExecuteScalar().ToString();
                }
                
                Console.WriteLine("Resumen de productos:");
                Console.WriteLine($"Cantidad: {totalProductos}");
                Console.WriteLine($"Monto total: {montoTotal} €");
                Console.WriteLine($"Precio promedio: {precioPromedio} €");
            }
        }
    }
}

Este segundo ejemplo utiliza tres comandos independientes para calcular estadísticas de la tabla Products. Cada comando se ejecuta con ExecuteScalar() y el resultado se convierte a cadena para mostrarlo en consola.

Etiquetas: DataReader SqlDataReader ADO.NET C# SQL Server

Publicado el 6-14 06:26