Utilizando la Biblioteca SqlHelper para ejecutar sentencias SQL

En una publicación pasada, agregamos a nuestra solución una clase que puede llevar a cabo la ejecución de consultas a un servidor SQL Server, vamos a ver en esta entrada cómo utilizar algunos de los métodos incluidos en la clase, tomando como la base de datos Northwind como ejemplo.

Conviértete en un Máster de C# y .NET

Antes de continuar, te invito a que te suscribas a mi academia de entrenamiento para desarrolladores .NET, en la que vas a aprender sobre C#, Blazor, Xamarin, .NET MAUI, ASP.NET, entre muchos otros temas por un mínimo precio.

Ejecutar consulta y llenar un DataSet en C# fácilmente

Si se quiere llenar un DataSet para trabajar posteriormente con él, podemos ejecutar el método denominado “ExecuteDataset”, el cual tiene 8 sobrecargas (Dar click en la imagen para ver en tamaño real):

Screen Shot 03-16-16 at 11.06 AM

La clase nos da una amplia gama de sobrecargas para poder pasar todo tipo de parámetros necesarios para llevar a cabo la ejecución de una consulta y posterior llenado de un Dataset, como ejemplo, vamos a ocupar el segundo método:

SqlHelper.ExecuteDataset(string, System.Data.CommandType, string)

cuya definición es:

public static System.Data.DataSet ExecuteDataset(string connectionString, System.Data.CommandType commandType, string commandText)

Es decir, debemos pasar como primer parámetro una cadena de conexión (Existe otro método para pasar directamente un objeto ConnectinString), para cuestiones de simplicidad, he creado una clase que mantiene la cadena de conexión centralizada:

public static class GlobalData
{
public static string ConnectionString { get; set; }
static GlobalData()
{
ConnectionString = @"Data Source=.\SQLSERVER;Initial Catalog=Northwind;Integrated Security=True";
}
}

Debemos crear una variable para almacenar la consulta que deseemos ejecutar, en mi caso será la siguiente:

var sqlQuery = "SELECT * FROM Customers";

Listo, ya podremos utilizar el método con la información previamente definida, colocando el resultado de la ejecución de tipo DataSet en una nueva variable:

var newDataSet = SqlHelper.ExecuteDataset(
GlobalData.ConnectionString,
CommandType.Text, sqlQuery);
var customers = newDataSet.Tables[0];

Si deseamos consultar el resultado, debemos obtener una de las tablas de la consulta en primer lugar:

var customers = newDataSet.Tables[0];

para posteriormente utilizar Linq para llevar a cabo la consulta (Debemos utilizar un método especial llamado .AsEnumerable para poder realizar consultas con Linq, que se encuentra en el ensamblado System.Data.DataSetExtensions), y como buena práctica, definir un nuevo tipo anónimo para poder utilizar las propiedades desde código:

var query = from customer in customers.AsEnumerable()
select new
{
  CompanyName = customer.Field<string>("CompanyName"),
  ContactName = customer.Field<string>("ContactName")
};

Por último, podemos recorrer el resultado de la consulta Linq e imprimir la información necesaria:

foreach (var customer in query)
{
	Debug.WriteLine(customer.CompanyName);
}

Ejecutar una consulta y llenar un DataReader en C# fácilmente:

Para llevar a cabo la ejecución de una consulta y rellenar un DataReader, disponemos de los siguientes métodos:

Screen Shot 03-19-16 at 12.14 PM

En esta demostración, utilizaremos el método:

public static System.Data.SqlClient.SqlDataReader ExecuteReader(string connectionString, System.Data.CommandType commandType, string commandText)

Podemos observar, que se nos pide como primer parámetro una cadena de conexión, como segundo el tipo de comando (si es consulta normal o un stored procedure), y como tercer, la consulta como tal.

En primer lugar, definiremos en una variable la consulta que deseamos ejecutar:

var sqlQuery = "SELECT * FROM Customers";

En segundo lugar, llamaremos al método que nos interesa, pasándole como referencia la cadena de conexión que definimos en el post anterior, seguido por el tipo de enumeración que deseamos aplicar, y la consulta definida previamente. Cabe destacar, que utilizaremos un using para cerrar la conexión y eliminar la instancia una vez que la dejemos de utilizar:

using (var newDataReader = SqlHelper.ExecuteReader(
  GlobalData.ConnectionString,
  CommandType.Text, sqlQuery))

Por último, haremos un recorrido por el datareader e imprimiremos la información deseada:

while (newDataReader.Read())
{
  var customerInfo = string.Format(
  "Company Name: {0}, ContactName: {1}",
  newDataReader.GetString(1),
  newDataReader.GetString(2));
  Debug.WriteLine(customerInfo);
}

Quedando el código completo del método, de la siguiente manera:

private void StartDataReaderDemo() {
  //Utilizando SqlHelper para llenar un DataReader
  var sqlQuery = "SELECT * FROM Customers";
  using(var newDataReader = SqlHelper.ExecuteReader(
  GlobalData.ConnectionString, CommandType.Text, sqlQuery)) {
    while (newDataReader.Read()) {
      var customerInfo = string.Format("Company Name: {0}, ContactName: {1}", newDataReader.GetString(1), newDataReader.GetString(2));
      Debug.WriteLine(customerInfo);
    }
  }

}

Ejecutar consulta a un Stored Procedure y llenar un DataReader fácil en C#

La forma para llevar a cabo una consulta a un procedimiento almacenado, conlleva básicamente los mismos pasos que anteriormente, con la diferencia, que debemos especificar el nombre del procedimiento almacenado en lugar de la consulta:

var sqlQuery = "Sales by Year";

En segundo lugar, debemos definir un arreglo de tipo SqlParameter, definiendo los parámetros que deseamos pasar:

var param1 = new SqlParameter {ParameterName = "@Beginning_Date", Value = new DateTime(1995, 1, 1) };
var param2 = new SqlParameter { ParameterName = "@Ending_Date", Value = new DateTime(1997, 1, 1)};
SqlParameter[] parameters = new[] {param1, param2};

Lo demás, es prácticamente lo mismo, el código completo del método se encuentra a continuación:

private void StartDataReaderDemo2() {
  //Utilizando SqlHelper para llenar un DataReader a través de un stored procedure
  var sqlQuery = "Sales by Year";
  var param1 = new SqlParameter {
    ParameterName = "@Beginning_Date",
    Value = new DateTime(1995, 1, 1)
  };
  var param2 = new SqlParameter {
    ParameterName = "@Ending_Date",
    Value = new DateTime(1997, 1, 1)
  };
  SqlParameter[] parameters = new[] {
    param1,
    param2
  };
  using(var newDataReader = SqlHelper.ExecuteReader(
  GlobalData.ConnectionString, CommandType.StoredProcedure, sqlQuery, parameters)) {
    while (newDataReader.Read()) {
      var customerInfo = string.Format("Order ID: {0}, Subtotal{1}", newDataReader.GetInt32(1), newDataReader.GetDecimal(2));
      Debug.WriteLine(customerInfo);
    }
  }
}

Ejecutar una consulta en C# y devolver un sólo valor (Scalar) fácil

Como bien es sabido, para ejecutar una consulta y devolver un sólo valor a través de un SqlCommand, debemos ejecutar un el método ExecuteNonQuery().

Es fácil realizar una ejecución de este método de forma controlada a través de la biblioteca SqlHelper, ya que contiene métodos que nos facilitarán dicha tarea. Esto nos permitirá devolver un valor con tan sólo 2 líneas de código:

private void StartScalarDemo()
{
  var query = "SELECT CompanyName FROM Customers WHERE CustomerID = 'BLAUS'";
  var result = SqlHelper.ExecuteScalar(GlobalData.ConnectionString, CommandType.Text, query);
  Debug.WriteLine(result);
}

En primer lugar, hemos de definir la sentencia a ejecutar, mientras que en la siguiente ejecutaremos el método denominado ExecuteNonQuery que se encargará de llevar a cabo todo el proceso correspondiente al manejo de apertura y cierre de la base de datos, así como la gestión de errores.

Ejecutar una consulta del tipo NonQuery en C# fácilmente

Si lo que deseamos es llevar a cabo la ejecución de una consulta que no devuelva información de la base de datos (tal como un insert o un delete), la lógica será similar al ejemplo anterior, con la diferencia de que el método que hemos de ejecutar es ExecuteNonQuery, que nos devolverá el número de filas afectadas, y el cual ejecutaremos de la siguiente forma en el caso de querer insertar información:

        private void StartNonQueryDemo1()
        {
            String query = "";
            query = query + "INSERT INTO [dbo].[Customers] " + "\n";
            query = query + " ([CustomerID] " + "\n";
            query = query + " ,[CompanyName] " + "\n";
            query = query + " ,[ContactName] " + "\n";
            query = query + " ,[ContactTitle] " + "\n";
            query = query + " ,[Address] " + "\n";
            query = query + " ,[City] " + "\n";
            query = query + " ,[Region] " + "\n";
            query = query + " ,[PostalCode] " + "\n";
            query = query + " ,[Country] " + "\n";
            query = query + " ,[Phone] " + "\n";
            query = query + " ,[Fax]) " + "\n";
            query = query + " VALUES " + "\n";
            query = query + " ('XYZ' " + "\n";
            query = query + " ,'HECTORS COMPANY' " + "\n";
            query = query + " ,'HÉCTOR PÉREZ' " + "\n";
            query = query + " ,'M.C.C' " + "\n";
            query = query + " ,'AV. HOGWARTS' " + "\n";
            query = query + " ,'MAGICLAND' " + "\n";
            query = query + " ,'REGIONLAND' " + "\n";
            query = query + " ,'99999' " + "\n";
            query = query + " ,'UK' " + "\n";
            query = query + " ,'2222' " + "\n";
            query = query + " ,'2222')";

            var result = SqlHelper.ExecuteNonQuery(GlobalData.ConnectionString, CommandType.Text, query);
            Debug.WriteLine("Registros agregados: {0}", result);
        }

En caso de desear eliminar el registro insertado en el ejemplo anterior, o bien, algún otro, debemos hacer una ejecución como en el siguiente ejemplo:

        private void StartNonQueryDemo2()
        {
            String query = "DELETE FROM [Customers] WHERE [CustomerID] = 'XYZ'";

            var result = SqlHelper.ExecuteNonQuery(GlobalData.ConnectionString, CommandType.Text, query);
            Debug.WriteLine("Filas eliminadas: {0}", result);
        }

Hemos visto que la utilización de la biblioteca SqlHelper es de mucha ayuda a la hora de programar, lo único que falta es que la integres a tus proyectos si te ha gustado. De nuevo, dejo el link de github si deseas integrar una biblioteca de clases de utilidades que se irán agregando poco a poco.

Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada.