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 unSqlDataReader. - Usar un bucle
whileconRead()para recorrer todas las filas. - Acceder a los valores de cada columna mediante el indizador por nombre de columna (recomendado) y convertir a
stringconToString(). - Cerrar el lector y la conexión (aquí mediante
using, que llama automáticamente aDispose).
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.