domingo, 13 de octubre de 2013

VENTAS 2 - Crear las Clases en C#

VENTAS 2. Creación de Clases en C#

Una vez definida la base de datos, ahora procedemos a crear las clases, para evitar que tu aplicación sufra retrasos y estar tratando de averiguar como empezaras la programación, deberás tener presente las siguientes recomendaciones:

  • Primero, debes crear por cada tabla de SqlServer una clase que coincida con los campos y nombre de la tabla.
  • Segundo, debes agregar las clases adicionales que usaras y tienen una relación directa con estas tablas, por ejemplo las herencias, las interfaz y otras.


1. Agregando Clases Padre o Principales

Una clase que uso constantemente es una que me simplifica las operaciones de acceso y ejecución de ordenes de SqlServer desde C#, a esta la llamo la clase CDatos.

El código de CDatos ha sido mejorado respecto al anterior ya que ahora este no provocará caída de la aplicación, sino nos enviara un mensaje en caso de EjecutarComando y un valor nulo en caso de EjecutarConsulta, este tiene el siguiente código:

 Código Fuente de la Clase CDatos

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace AppVenta
{
    public class CDatos
    {
        string cadenaDeConexion = @"Data Source=(local);Initial Catalog=bdVentas;Integrated Security=True";

        public string Mensaje;

        public bool EjecutarComando(string textoSql)
        {
            try
            {
                //Para la cadena de conexión
                string sCnn = cadenaDeConexion;
                //Creamos la conexión
                SqlConnection cnn = new SqlConnection(sCnn);
                //Texto del comando insert
                string iTexto = textoSql;
                //Creamos el comando con su texto y conexión
                SqlCommand cmd = new SqlCommand(iTexto, cnn);
                cmd.CommandType = CommandType.Text;
                //abrimos la conexión y ejecutamos el comando
                cnn.Open();
                //Ejecutamos el comando sql
                cmd.ExecuteNonQuery();
                //Cerramos la conexión
                cnn.Close();
                //Agregamos el Mensaje de Correcto
                Mensaje = "Comando realizado con exito...";
                return true;
            }
            catch
            {
                Mensaje = "0: Error en Conexión con la base de datos o el comando de SqlServer";
                return false;
            }
        }

        public DataTable EjecutarConsulta(string textoSQL)
        {
            try
            {
                //Creamos la cadena de conexion
                string sCnn = cadenaDeConexion;
                //Creamo el comando de sql para listar
                string sSel = textoSQL;
                //Creamos el adaptador que capturara los datos
                SqlDataAdapter da = new SqlDataAdapter(sSel, sCnn);
                //Creamos un data table que contendra los datos
                DataTable dt = new DataTable();
                //Llenamos el data table con el adaptador
                da.Fill(dt);
                //Colocando Mensaje
                Mensaje = "Comando realizado con éxito...";
                return dt;
            }
            catch
            {
                Mensaje = "0: Error en Conexión o Consulta de SqlServer...";
                return null;
            }
        }
    }
}

Interfaz

Una interfaz es una forma de acceder a una clase, cuando uno desea acceder a los datos u operaciones de una clase, puede hacer lo mediante la interfaz, la ventaja de una interfaz es que varios objeto pueden usar una interfaz y así puede generalizarse la solución de un problema para varias clases y programarlas en conjunto.

También crearemos una interfaz que nos permitirá generalizar el código y hacer las operaciones de insertar, modificar y eliminar de forma similar para evitar desorden a la hora de codificar estos métodos, las interfaz también permiten la re utilización del código, esta interfaz es la siguiente:

 Código Fuente de la Interfaz IMantenimiento

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AppVenta
{
    public interface IMantenimiento
    {
        bool Insertar();

        bool Modificar();

        bool Eliminar();
    }
}

2. Creación de Clases

Ahora necesitamos crear las clases que corresponden a las tablas de la base de datos, primero hemos desarrollado las clases anteriores ya que estas clases dependen de la clase CDatos y de la interfaz CMantenimiento.

 Código de la clase CProducto

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LogicaVenta
{
    public class CProducto : CDatos, IMantenimiento
    {
        private int idProducto;

        public int IdProducto
        {
            get { return idProducto; }
            set { idProducto = value; }
        }
        private string nombre;

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }
        private string descripcion;

        public string Descripcion
        {
            get { return descripcion; }
            set { descripcion = value; }
        }
        private double precioUnitario;

        public double PrecioUnitario
        {
            get { return precioUnitario; }
            set { precioUnitario = value; }
        }
        private string observacion;

        public string Observacion
        {
            get { return observacion; }
            set { observacion = value; }
        }

        public bool Insertar()
        {
            throw new NotImplementedException();
        }

        public bool Modificar()
        {
            throw new NotImplementedException();
        }

        public bool Eliminar()
        {
            throw new NotImplementedException();
        }
    }
}


 Código de la clase CCLiente

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LogicaVenta
{
    class CCliente : CDatos, IMantenimiento
    {
        int idCliente;

        public int IdCliente
        {
            get { return idCliente; }
            set { idCliente = value; }
        }
        string nombre;

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }
        string direccion;

        public string Direccion
        {
            get { return direccion; }
            set { direccion = value; }
        }
        string telefono;

        public string Telefono
        {
            get { return telefono; }
            set { telefono = value; }
        }
        string observacion;

        public string Observacion
        {
            get { return observacion; }
            set { observacion = value; }
        }
        public bool Insertar()
        {
            throw new NotImplementedException();
        }

        public bool Modificar()
        {
            throw new NotImplementedException();
        }

        public bool Eliminar()
        {
            throw new NotImplementedException();
        }
    }
}

 Código de la clase CDetalle

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LogicaVenta
{
    class CDetalle : CDatos, IMantenimiento
    {
        int fkVenta;

        public int FkVenta
        {
            get { return fkVenta; }
            set { fkVenta = value; }
        }
        int fkProducto;

        public int FkProducto
        {
            get { return fkProducto; }
            set { fkProducto = value; }
        }
        int cantidad;

        public int Cantidad
        {
            get { return cantidad; }
            set { cantidad = value; }
        }
        double precioUnitario;

        public double PrecioUnitario
        {
            get { return precioUnitario; }
            set { precioUnitario = value; }
        }

        public bool Insertar()
        {
            throw new NotImplementedException();
        }

        public bool Modificar()
        {
            throw new NotImplementedException();
        }

        public bool Eliminar()
        {
            throw new NotImplementedException();
        }
    }
}


 Código de la clase CVenta

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LogicaVenta
{
    class CVenta : CDatos, IMantenimiento
    {
        int idVenta;

        public int IdVenta
        {
            get { return idVenta; }
            set { idVenta = value; }
        }
        DateTime fecha;

        public DateTime Fecha
        {
            get { return fecha; }
            set { fecha = value; }
        }
        string observacion;

        public string Observacion
        {
            get { return observacion; }
            set { observacion = value; }
        }
        int fkCliente;

        public int FkCliente
        {
            get { return fkCliente; }
            set { fkCliente = value; }
        }

        public bool Insertar()
        {
            throw new NotImplementedException();
        }

        public bool Modificar()
        {
            throw new NotImplementedException();
        }

        public bool Eliminar()
        {
            throw new NotImplementedException();
        }
    }
}

Diagrama de Clases

El diagrama nos nuestra la clase CDatos como una clase Principal de la cual hereda su comportamiento a todas las demás tablas, también tenemos la interfaz IMantenimiento mediante la cual nos permitirá acceder a las clases de forma única, reduciendo así el código.



VENTAS 1. Aplicación de Ventas - Crear la Base de Datos

VENTAS 1. Creación de la Base de Datos

Al desarrollar una aplicación, no podemos hacer muchos trabajos si no tenemos armada la base de datos, podríamos hacer el diseño de los formularios o mejor dicho los bosquejos de estos, el entorno principal de menú y algunos otros detalles de la aplicación pero no podríamos desarrollar la aplicación de datos en si y la programación pues nos faltarían datos para hacerlo, por ello te sugiero las siguientes recomendaciones.
  • Primero, tener el diseño de la base de datos.
  • Segundo, tener el código de la base de datos y la base de datos en forma física, es decir ya creada.
  • Tercero, también deberás ya estar creando los principales procedimientos almacenados y/o las instrucciones que permitirán hacer el mantenimiento de la base de datos.
Las programación también se pueden desarrollar a la par con la base de datos, pero te convendría tener un avance mayor en tu base de datos ya que un error o una modificación el la base de datos provocará que la programación sea reestructurada e incluso se rehaga nuevamente.

Conociendo esto ahora procederemos a armar estos tres elementos:

1. Diseño de la Base de Datos

Haremos una aplicación para el control de las ventas de productos en una tienda que tiene las siguientes reglas que ponemos en resumen.
  • Un cliente puede participar en varias ventas como un comprador, del cliente necesitamos su nombre, dirección, teléfono y de la venta necesitamos el numero de la venta, la fecha de venta y alguna observación que necesitemos anotar.
  • En toda venta se puede comprar varios productos, entre los detalles que se debe tener son la cantidad de productos que se compran, el precio al que se compra.
  • Del producto necesitamos su nombre, una descripción, su precio unitario y un lugar donde podamos anotar algunas observaciones.


2. Creación de la Base de Datos

Una vez que tenemos el diseño de la base de datos, ahora procedemos a la creación de la base de datos siguiendo siempre la estructura del diseño.

Código en SqlServer para la Base de Datos

use master;
go
drop database bdVentas;
go
create database bdVentas;
go
use bdVentas;
go
/*
* CREAR TABLAS
*/
create table tCliente
(
                idCliente int primary key identity,
                nombre varchar(170) not null,
                direccion varchar(170),
                telefono varchar(20),
                observacion text
);
go
create table tVenta
(
                idVenta int primary key identity,
                fecha datetime,
                observacion text,
                fkCliente int,
                foreign key(fkCliente) references tCliente(idCliente)
);
go
create table tProducto
(
                idProducto int primary key identity,
                nombre varchar(170) not null,
                descripcion text,
                precioUnitario money,
                observacion text
);
go
create table tDetalle
(
                fkVenta int,
                fkProducto int,
                cantidad int,
                precioUnitario money,
                foreign key(fkVenta) references tVenta(idVenta),
                foreign key(fkProducto) references tProducto(idProducto),
                primary key (fkVenta, fkProducto)
);
go

3. Instrucciones de Mantenimiento de la Base de Datos

Ahora que ya tenemos la base de datos, debemos proceder a crear los procedimientos almacenados, vistas e instrucciones para el mantenimiento y consulta de los datos de las tablas, en esta parte no usaremos procedimientos almacenados, por ahora usaremos las instrucciones básicas de SqlServer.

Código en SqlServer para la Base de Datos

/*
* INSERCIÓN DE DATOS
*/
/*Insertar personas*/
insert into tCliente(nombre,direccion,telefono,observacion) values('Juan Perez','Av. Sol 233','546565','N.A.');
/*Insertar productos*/
insert into tProducto(nombre,descripcion,precioUnitario,observacion) values('Televisor LED 50p LG','N.N.N',1586.45,'N.A.');
/*Insertar venta*/
insert into tVenta(fecha,observacion,fkCliente) values('12/12/12','NN.AA.',1);
/*Insertar detalle*/
insert into tDetalle(fkVenta,fkProducto,cantidad,precioUnitario) values(1,1,15,2.5);
go
/*
* MODIFICACION DE DATOS
*/
/*Modificar clientes*/
update tCliente set nombre='qqq',direccion='ppp',telefono='kkk',observacion='mmm' where idCliente = 1;
/*Modificar productos*/
update tProducto set nombre='www',descripcion='ggg',precioUnitario=6.55,observacion='ttt' where idProducto = 1;
/*Modificar ventas*/
update tVenta set fecha='10/10/10', observacion='hhh' where idVenta=1;
/*Modificar detalles*/
update tDetalle set fkVenta=1,fkProducto=1,cantidad=47,precioUnitario=4.5 where fkVenta=1 and fkProducto=1;
go
/*
* ELIMINAR DATOS
*/
/*Eliminar detalles*/
delete from tDetalle where fkVenta=1 and fkProducto=1;
/*Eliminar ventas*/
delete from tVenta where idVenta=1;
/*Eliminar productos*/
delete from tProducto where idProducto=1;
/*Eliminar clientes*/
delete from tCliente where idCliente=1;
go
/*
* CONSULTAS
*/
select * from tCliente;
select * from tProducto;
select * from tVenta;
select * from tDetalle;
/*Buscar Productos por Nombre*/
select * from tProducto where nombre like '%LED%';
/*Buscar Prodocutos por ID*/
select * from tProducto where idProducto=1;
/*Buscar clientes por Nombre*/
select * from tCliente where nombre like '%juan%';
/*Buscar Clientes por ID*/
select * from tCliente where idCliente=1;
/*Listar las ventas de un Cliente*/
select * from tCliente join tVenta on tCliente.idCliente = tVenta.idVenta where idCliente=1;
/*Listar la venta con sus detalles*/
select * from tVenta join tDetalle on tVenta.idVenta=tDetalle.fkVenta;


















1.4. Uso de Datos de SqlServer en Controles C#

Llenar controles ListBox, ComboBox con Datos de Una Tabla de SqlServer

El manejo de ListBox y ComboBox es similar en su uso, aquí usaremos un ComboBox, pero el código es similar si se usa un control ListBox.

Antes de trabajar el código debemos tener creada la clase CProducto, y la clase CDatos que hicimos en la anterior pagina, estas clases son necesarias puesto que tienen la conexión con SqlServer y las operaciones de consultas. El objetivo no es hacer el código desde el inicio, ese código ya lo tenemos desarrollado y nos permitirá centrarnos en el uso de los controles.


Forma 1. Llenar un ComboBox con los datos de un DataTable

             /*Llenar el DataTable*/
            DataTable resultado = oProducto.Listar();
            /*Hace que el DataTable se enlace con el ComboBox*/
            cboDatos.DataSource = resultado;
            /*Indicando que columna del DataTable obtiene el valor del Combo*/
            cboDatos.ValueMember = "idProducto";
            /*Indicando que columna del DataTable se muestra en el Combo*/
            cboDatos.DisplayMember = "nombre";

Obtener los valores del ComboBox

             /*Obtiene el dato seleccionado del ComboBox*/
            string elemento = cboDatos.SelectedValue.ToString();
            /*Mostrando el Valor del elemento*/
            MessageBox.Show(elemento);



Forma 2. Llenar un ComboBox con los datos de un DataTable

             /*Llenar el DataTable*/
            DataTable resultado = oProducto.Listar();
            /*Hace que el DataTable se enlace con el ComboBox*/
            cboDatos.DataSource = resultado;
            /*Indicando que columna del DataTable obtiene el valor del Combo*/
            cboDatos.ValueMember = resultado.Columns[0].ColumnName;
            /*Indicando que columna del DataTable se muestra en el Combo*/
            cboDatos.DisplayMember = resultado.Columns[1].ColumnName;
Nota Importante:
  • Cuando usamos Columns[0].ColumnName nos estamos refiriendo al nombre que tiene la columna del DataTable, de esta forma podemos evitarnos estar verificando que nombre le pusimos a la columna y solo nos centraríamos en el orden.
  • Existen varias formas de llenar un ComboBox con datos de un DataTable, aquí te he querido mostrar las mas sencillas e importante, pues el objetivo no es hacer código complicado. 


Llenar controles DataGridView con Datos de Una Tabla de SqlServer

Los controles DataGridView son muy usados para mostrar colecciones de datos, por ejemplo los resultados de una búsqueda, el listado de datos y/o similares.

Llenar un DataGridView con Datos de un DataTable

             /*Creando un DataTable y llenandole datos*/
            DataTable resultado = oProducto.Listar();
            /*Asignando los datos al DataGridView*/
            dgvDatos.DataSource = resultado;
Nota. Todas las columnas tienen el mismo ancho y los nombres de las cabeceras tienen los mismos valores del las columnas del DataTable. Por ello esto debes cambiarlo lego según tus necesidades.

Elementos Necesarios para Mejorar e DataGridView

Cambiando Tamaño a las Columnas de un DataGridView

             /*Colocando el tamaño de las columnas de un DataGridView*/
            dgvDatos.Columns[0].Width = 70;
            dgvDatos.Columns[1].Width = 250;
            dgvDatos.Columns[3].Width = 70;

Cambiando Textos de las columnas en la cabecera del DataGridView

             /*Cambiando las cabeceras del DataGridView as la columns 0, 1, 3, 4*/
            dgvDatos.Columns[0].HeaderText = "Código del Producto";
            dgvDatos.Columns[1].HeaderText = "Nombre del Producto";
            dgvDatos.Columns[3].HeaderText = "Precio Unitario";
            dgvDatos.Columns[4].HeaderText = "Fecha/Fabricación";

Ocultando Columna de un DataGridView

             /*Ocultando la columna 5 del DataGridView*/
            dgvDatos.Columns[5].Visible = false;

oProducto.Listar();

No olvides que este objeto resuelve el acceso a los datos de SqlServer y nos simplifican el trabajo, su código lo puedes encontrar en la siguiente dirección:










jueves, 10 de octubre de 2013

OtrosTemas

PROGRAMACIÓN ORIENTADA A OBJETOS EN CAPAS

Les voy a explicar una experiencia propia y espero que le sirva de ayuda para quienes tienen que desarrollar algún sistema y se sienten medios perdidos para poder arrancar.

Historia

Hace un tiempo, aquellos años en los que aun no nacía, los sistemas informáticos no tenían bases de datos y existían lenguajes que tenían bases de datos que eran casi propias de cada lenguaje, en Cobol por ejemplo teníamos archivos tipo texto armados a mano, lo mismo en Basic y Pascal.
Luego sucedió algo aparecieron Clipper, Fox, ahí ya se comenzó a separar el lenguaje de programación de la base de datos.
Esto significa por ejemplo que Access, lo podemos usar desde JAVA, Visual Basic, C#, etc., la idea cambio y en principio tenemos un motor de base de datos o servidor de base de datos como Access, SQL, Oracle, MySQL y por otro lado un lenguaje de programación que accede eso Insertando, Modificando, Listando, etc.


Si nos ponemos a mirar tenemos 2 cosas separadas, por ejemplo una Base de Datos en SQL Server puede ser vista, desde el propio SQL Server o también desde un programa hecho en JAVA, C# o Phyton.
Si bien al parecer nuestros problemas se habían resuelto, pues era muy fácil crear una aplicación hecha para Windows y que corra en una red local. Pero en el mundo de la informática las cosas cambian, pues aparece el auge de la Web que vivimos hace años y aun continuamos viviendo y espera perpetuarse por siempre, ahora los sistemas de base de datos única se debía leer desde un software de red local y además desde la web, por tanto se agrega otro software posible a nuestro sistema hecho especialmente para la base de datos.


En la actualidad para aumentar la complejidad llegamos a los celulares, ahora el sistema tiene una base de datos, que se lee desde un PC, también desde la Web y también desde un teléfono móvil o celular.
Hasta ese momento la cosa era fácil se hace 1 base de datos y 3 programas totalmente distintos para cada dispositivo, solución fácil, pero claro había que hacer tres programas desde cero cada vez por supuesto esto aumentaba considerablemente los costos, pues tiene que hacerse cada uno le los tres programas, esto representa horas de trabajo, horas de personal, horas maquina, etc.

Actualidad

Fue ahí cuando aparecen los nuevos lenguajes con sus nuevas posibilidades y formas de programar, donde la programación orientada a objetos fue fundamental, de esta forma podíamos dividir ese software en capas independientes. Actualmente el software se divide en capas, la primera la base de datos, la segunda la capa del negocio, la tercera la capa de presentación. El siguiente esquema muestra esta división:

La capa de datos.

Es la base de datos, donde se encuentran creadas las tablas, vistas, procedimientos, trigger, etc.
La capa de acceso a datos.

Cuya misión es acceder a la base de datos y traer la información (registros de las tablas, cuando consultamos, o listamos), o llevarlos a la base de datos (cuando agregamos o modificamos), con esto logramos que todo ese código que puede estar hecho en C# lo re‐utilicemos sin importar si estamos en Web o Red Local (o Celulares).

La capa del negocio.

Consiste en las Entidades Relevantes, o sea Clases en C# que permitan contener esa información que se leyó desde la base de datos mediante el Acceso a Datos, será este un intermediario para que luego la interfaz muestre eso para PC o Web, todo el segmento de código C# de estas Clases de Entidades Relevantes se re‐utiliza sin importar de si es para PC o Web.

La capa de presentación.

Necesitamos que nuestro sistema pueda ser vistos en una PC local, en el Internet, o desde un celular, aquí creamos el software necesario para este proceso, es decir, la aplicación que correrá en un equipo local, la aplicación que correrá en la Web y la aplicación que correrá desde un celular.

Futuro

El día de mañana podemos utilizar el mismo sistema con otra base de datos que no sea Access, por ejemplo MySQL, cambiando solo el Acceso a datos, quedando el esquema así:
Logrando de esta forma un software que brinde la posibilidad de trabajar con una u otra base de datos (o más), sin necesidad de hacerlo todo de nuevo ya que reutilizamos el código.


En síntesis el desarrollo de un software en capas tiene muchísimas ventajas, piensen en cuantas horas de programación perderían si tienen que diseñar un sistema diferente para cada tipo de interfaz que se tenga que utilizar. Por otro lado, hay lenguajes más complejos que otros y cada uno con sus ventajas y desventajas. Muchas veces no van a tener la posibilidad de elegir con el lenguaje que tienen que programar por eso es bueno tener idea de cómo funcionan y para que se utilizan en general los distintos lenguajes de programación.

Por eso en la medida de lo posible cuando desarrollen un software traten siempre de mirar un poco mas delante en el tiempo teniendo en cuenta que posiblemente tendrán que modificarlo para agregarle prestaciones nuevas.

1.3. Mantenimiento de una Tabla de SQL con un Formulario Usando la Clase CDatos

Desarrollando el Mantenimiento de Datos de Una Tabla

Cuando hacemos un programa con base de datos u otra tecnología donde necesitemos guardar los datos de forma persistente, es decir, la guardemos para su posterior uso; necesitamos realizar el mantenimiento de los datos, en este caso haremos como ejemplo el mantenimiento de la tabla de SqlServer denominada tProducto. El mantenimiento consiste en realizar las siguientes operaciones:
  • Insertar registros en la tabla, significa agregar nuevos datos.
  • Modificar registros, con esta operación podemos cambiar los datos ya existentes de un registro, la modificación casi siempre de realiza haciendo referencia al ID del registro.
  • Eliminar registro, realizamos el borrado del registro, normalmente se borra haciendo referencia al ID del registro.
  • Listas y consultas, estas operaciones nos permiten ver los registros grabados en una tabla, aquí pueden hacerse la búsquedas, consultas anidadas, etc.

La base de Datos en SqlServer

Ante de desarrollar un sistema o programa que maneje una base de datos, debemos contar con la base de datos bien diseñada y codificada, es decir, ya debemos tener la base de datos en forma física. Es por esta razón que pongo aquí el código de la base de datos que tu deberás correr en tu gestor SQL Server.


 CÓDIGO DE LA BASE DE DATOS
El siguiente código tiene incluye la creación de la base de datos, la creación de la tabla y las operaciones básicas de mantenimiento como son insertar, modificar, eliminar y algunas consultas necesarias.
 /*Cambiando el formato de fecha a día,mes,año el formato debe coincidir con C#*/
SET DATEFORMAT dmy;
/*Esta base de datos tiene una sola  tabla, es solo un ejemplo*/
use master;
go
drop database bdAlmacen;
go
Create database bdAlmacen;
go
use bdAlmacen;
go
Create Table tProducto
(
idProducto int primary key identity,
nombre varchar(100),
cantidad int,
precio money,
fecFab datetime, --Fecha de fabricación
observacion text
);
go
/*Listar todos los productos*/
select * from tProducto;
/*Insertar registros a la tabla*/
insert into tProducto(nombre, cantidad, precio, fecFab, observacion) values('Monitor LED 18p',7, 125.4, '12/11/2012','N.');
/*Modificar datos del producto*/
update tProducto set nombre='Monitor LCD 15p', cantidad=5, precio=90.5, fecFab='19/05/2008', observacion='S.' where idProducto=1;
/*Eliminar un producto por id*/
--delete from tProducto where idProducto=1;
/*Buscar un producto por su codigo*/
select * from tProducto where idProducto=1;
/*Buscar un producto por nombre*/
select * from tProducto where nombre like '%LCD%';
/*Buscar un producto por Fecha*/
select * from tProducto where fecFab = '19/05/2008';

FinDelCódigo 

La clase CDatos

He construido una clase básica para hacer la conexión de SqlServer con C#, esta clase tiene dos métodos principales, estos son:

Método EjecutarComando

Lo usaremos para ejecutar ordenes Sql desde C#, la característica de las ordenes es que debe ser de tipo comando, es decir, no devolver datos, por ejemplo esto son:

  • insert
  • update
  • delete
  • procedimientos almacenados que no devuelven datos.

Método EjecutarConsulta

También lo usamos para ejecutar una orden Sql desde C#, las ordenes a ejecutar con este metodo son de tipo consultas, significa que devuelven datos, estas ordenes son:
  • select
  • procedimientos almacenados que devuelven datos de tipo select.
Esta clase puede ser reutilizada y/o mejorada para otros proyectos.

  CÓDIGO DE LA CLASE CDatos.cs
Para entender esta clase deberás leer los comentarios ya que estos indican para que usamos cada orden, he querido hacer la clase más simple posible ya que el objetivo de esto es que se pueda entender sin complicaciones de ningún tipo como se usan los comandos, la clase y como esta estructurado.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
//AppProducto, Este es el nombre de la aplicación, deberás cambiarlo si usas otro nombre
namespace AppProducto
{
    public class CDatos
    {
        //Aquí esta la cadena de conexión a SqlServer, dependiendo de tu proyecto, esto debes cambiarlo
        //normalmente se cambia el nombre del servidor y el nombre de la base de datos
        string cadenaDeConexion = @"Data Source=(local);Initial Catalog=bdAlmacen;Integrated Security=True";

        public string EjecutarComando(string textoSql)
        {
            //Para la cadena de conexión
            string sCnn = cadenaDeConexion;
            //Creamos la conexión
            SqlConnection cnn = new SqlConnection(sCnn);
            //Texto del comando insert
            string iTexto = textoSql;
            //Creamos el comando con su texto y conexión
            SqlCommand cmd = new SqlCommand(iTexto, cnn);
            cmd.CommandType = CommandType.Text;
            //abrimos la conexión y ejecutamos el comando
            cnn.Open();
            //Ejecutamos el comando sql
            cmd.ExecuteNonQuery();
            //Cerramos la conexión
            cnn.Close();
            return "Comando realizado con exito...";
        }

        public DataTable EjecutarConsulta(string textoSQL)
        {
            //Creamos la cadena de conexion
            string sCnn = cadenaDeConexion;
            //Creamo el comando de sql para listar
            string sSel = textoSQL;
            //Creamos el adaptador que capturara los datos
            SqlDataAdapter da = new SqlDataAdapter(sSel, sCnn);
            //Creamos un data table que contendra los datos
            DataTable dt = new DataTable();
            //Llenamos el data table con el adaptador
            da.Fill(dt);
            //Colocando datos al datagridview dgvNacionalidad
            return dt;
        }
    }
}
FinDelCódigo 

La Clase CProducto

Para poder realizar las operaciones de mantenimiento, vamos ha desarrollar la siguiente clase, esta clase representa la unión entre el C# y el SqlServer, es la clase de transición, en este caso usaremos lar ordenes Sql directamente.

Algo importante a tener en cuenta es que esta clase presenta una herencia, la clase padre es CDatos, por tanto esta clase cuenta con los métodos de su clase padre que son: EjecutarComando y EjecutarConsulta.

Nota que los campos y propiedades de la clase escrita en C# son los mismos que los campos que tenemos en la tabla tProducto de la base de datos. En sistemas grandes casi siempre se hace una clase por cada tabla de la base de datos donde coinciden los campos de la tabla con los de la clase en C# u otro lenguaje que uses.

 CÓDIGO DE LA CLASE CProducto.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace AppProducto
{
    class CProducto : CDatos
    {
        /*Aqui todos los campos deben coincidir con la base de datos*/
        int idProducto;

        public int IdProducto
        {
            get { return idProducto; }
            set { idProducto = value; }
        }
        string nombre;

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }
        int cantidad;

        public int Cantidad
        {
            get { return cantidad; }
            set { cantidad = value; }
        }
        double precio;

        public double Precio
        {
            get { return precio; }
            set { precio = value; }
        }
        DateTime fecFab;

        public DateTime FecFab
        {
            get { return fecFab; }
            set { fecFab = value; }
        }
        string observacion;

        public string Observacion
        {
            get { return observacion; }
            set { observacion = value; }
        }

        /*Metodos de la clase, segun las necesidades de la aplicacion*/
        /*Los siguientes metodos no retornan datos, es decir no son consultas*/
        public string Insertar()
        {
            string texto = "insert into tProducto(nombre, cantidad, precio, fecFab, observacion) values('" + Nombre + "'," + Cantidad + ", " + Precio + ", '" + FecFab.ToString("d/M/yyyy HH:mm:ss") + "','" + Observacion + "');";
            return EjecutarComando(texto);
        }
        public string Modificar()
        {
            string texto = "update tProducto set nombre='" + Nombre + "', cantidad=" + Cantidad + ", precio=" + Precio + ", fecFab='" + FecFab.ToString("d/M/yyyy") + "', observacion='" + Observacion + "' where idProducto=" + IdProducto + ";";
            return EjecutarComando(texto);
        }
        public string Eliminar()
        {
            string texto = "delete from tProducto where idProducto="+IdProducto+";";
            return EjecutarComando(texto);
        }
        /*Estos metodos retornan resultados pues con consultas*/
        public DataTable Listar()
        {
            string texto = "select * from tProducto;";
            return EjecutarConsulta(texto);
        }
        public DataTable ListarPorIdProducto()
        {
            string texto = "select * from tProducto where idProducto="+IdProducto+";";
            return EjecutarConsulta(texto);
        }
        public DataTable ListarPorNombre()
        {
            string texto = "select * from tProducto where nombre like '%" + Nombre + "%';";
            return EjecutarConsulta(texto);
        }
        public DataTable ListarPorFecha()
        {
            string texto = "select * from tProducto where fecFab = '" + FecFab.ToString("d/M/yyyy") + "';";
            return EjecutarConsulta(texto);
        }
    }
}

FinDelCódigo 

Nota Importante
En la clase usamos las ordenes de Sql, insert, update, delete, select estas están ensambladas usando las propiedades de la clase CPersona, tambien puedes observar el uso de los metodos EjecutarComando y EjecutarConsulta.

El formulario

El siguiente formulario deberá ser diseñado con sus nombres correspondientes y los controles definidos. Esta es la interfaz de usuario con la cual aquel que use la aplicación se va ha comunicar, en nuestro caso este formulario tiene las operaciones básicas de mantenimiento y consulta.


Este formulario presenta los siguientes controles:
  • txtIdProducto, es un control de tipo TextBox
  • txtNombre, es un control de tipo TextBox
  • txtCantidad, es un control de tipo TextBox
  • txtPrecio, es un control de tipo TextBox
  • txtObservacion, es un control de tipo TextBox, propiedad MultiLine en true
  • dtpFecha, es un control de tipo DateTimePicker
  • dgvDatos, es un control de tipo DataGridView, prodiedad ReadLine en true
  • btnInsertar, es un control de tipo Button
  • btnModificar, es un control de tipo Button 
  • btnEliminar, es un control de tipo Button
  • btnListar, es un control de tipo Button
  • btnBuscarId, es un control de tipo Button
  • btnBuscarNombre, es un control de tipo Button
  • Los controles de tipo Label, no tienen nombres pues no los hemos usado como parte del código.

Propiedades Desarrolladas en el Formulario

En este formulario hemos agregado una propiedad llamada oProducto, que es la instancia de la clase CPersona, ahora una vez que tenemos el objeto oProducto ya podemos usarlo en todo el formulario, el siguiente es el código para crear el objeto:


CODIGO PARA CREAR EL OBJETO oProducto
         /* Código Nuevo: Creando el objeto de tipo CProducto */
        CProducto oProducto = new CProducto();

FinDelCódigo 


En la figura siguiente te muestro como debe quedar este código en la aplicación general.

Figura Nº 1.

Métodos Codificados en el Formulario

Método LlenarObjeto()

Cuando usas controles, en estos puedes ingresar datos, estos datos al final son lo que se trabajan, es por ello que necesitamos un metodo LlenarObjeto que permitirá vaciar los datos que tienes en el formulario a el objeto oProducto, luego de esto tu podrás hacer las operaciones que necesites ya que los datos ya los tiene el objeto.

Importante
Ver la figura Nº1 para observar como debe quedar el código LlenarObjeto en tu formulario.

Código del Método LlenarObjeto
         /* Código Nuevo: Llenar el objeto con datos, este metodo hace que los de los controles pasen al objeto*/
        public bool LlenarObjeto()
        {
            try
            {
                try { oProducto.IdProducto = int.Parse(txtIdProducto.Text); }
                catch { oProducto.IdProducto = 0; }
                oProducto.Nombre = txtNombre.Text;
                oProducto.Observacion = txtObservacion.Text;
                oProducto.Precio = double.Parse(txtPrecio.Text);
                oProducto.FecFab = dtpFecha.Value;
                return true;//Devuelve verdadero cuando los datos son correctos
            }
            catch
            {
                return false;//Devuelve falso cuando los datos NO son correctos
            }
        }

FinDelCódigo 


Código de los Controles

Los controles del formulario necesitan código, en nuestro caso el código de todos los controles manipulan las operaciones del objeto oProducto.

 CÓDIGO DEL BOTÓN 
btnInsertar
         private void btnInsertar_Click(object sender, EventArgs e)
        {
            //Usando el Metodo de Formulario LlenarObjeto
            if (LlenarObjeto())
            {
                //Usando el metodo Insertar de oProducto
                MessageBox.Show(oProducto.Insertar());
                //Borrando los datos del DataGridView
                dgvDatos.DataSource = null;
            }
            else
            {
                //Mensaje en caso de error al llenar el objeto
                MessageBox.Show("Error al llenar los datos...");
            }
        }

FinDelCódigo 


CÓDIGO DEL BOTÓN 
btnModificar
         private void btnModificar_Click(object sender, EventArgs e)
        {
            //Usando el Metodo de Formulario LlenarObjeto
            if (LlenarObjeto())
            {
                //Ejecutar el metodo Modificar de oProducto
                MessageBox.Show(oProducto.Modificar());
                //Borrando los datos del DataGridView
                dgvDatos.DataSource = null;
            }
            else
            {
                MessageBox.Show("Error al llenar los datos...");
            }
        }

FinDelCódigo 


 CÓDIGO DEL BOTÓN 
btnEliminar
         private void btnEliminar_Click(object sender, EventArgs e)
        {
            try
            {
                //Asignando el Id del control al objeto oProducto
                oProducto.IdProducto = int.Parse(txtIdProducto.Text);
                //Ejecutando el método Eliminar de oProducto
                MessageBox.Show(oProducto.Eliminar());
                //Borrando los datos del DataGridView
                dgvDatos.DataSource = null;
            }
            catch
            {
                //Mostrando mensaje de error
                MessageBox.Show("Error Debes proporcionar el ID");
            }
        }

FinDelCódigo 


CÓDIGO DEL BOTÓN 
btnListar
         private void btnListar_Click(object sender, EventArgs e)
        {
            //Usando el metodo Listar de oProducto y mostrandolo en el DataGridView
            dgvDatos.DataSource = oProducto.Listar();
        }

FinDelCódigo 


 CÓDIGO DEL BOTÓN 
btnBuscarId
         private void btnBuscarId_Click(object sender, EventArgs e)
        {
            try
            {
                //Proporcionamos el Id al objeto oProducto
                oProducto.IdProducto = int.Parse(txtIdProducto.Text);
                //Ejecutamos el metodo ListarPorIdProducto
                dgvDatos.DataSource = oProducto.ListarPorIdProducto();
            }
            catch
            {
                //Mensaje de error
                MessageBox.Show("Falta Ingresar el ID");
            }
        }

FinDelCódigo 


CÓDIGO DEL BOTÓN 
btnBuscarNombre
         private void btnBuscarNombre_Click(object sender, EventArgs e)
        {
            try
            {
                //Proporcionamos el Nombre al objeto
                oProducto.Nombre = txtNombre.Text;
                //Ejecutamos el metodo ListarPorNombre
                dgvDatos.DataSource = oProducto.ListarPorNombre();
            }
            catch
            {
                //Mensaje de error
                MessageBox.Show("Falta Ingresar el Nombre");
            }
        }

FinDelCódigo 


 CÓDIGO DEL DATAGRIDVIEW (dgvDatos)
EVENTO CellClick
         /*Metodo CellClick del DataGridView, cuando hacemos clic en el DataGridView*/
        private void dgvDatos_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                //Pasando los datos del DataGridView a los Controles
                txtIdProducto.Text = dgvDatos.CurrentRow.Cells[0].Value.ToString();
                txtNombre.Text = dgvDatos.CurrentRow.Cells[1].Value.ToString();
                txtCantidad.Text = dgvDatos.CurrentRow.Cells[2].Value.ToString();
                txtPrecio.Text = dgvDatos.CurrentRow.Cells[3].Value.ToString();
                dtpFecha.Value = DateTime.Parse(dgvDatos.CurrentRow.Cells[4].Value.ToString());
                txtObservacion.Text = dgvDatos.CurrentRow.Cells[5].Value.ToString();
            }
            catch
            {
                MessageBox.Show("Posible error por falta de datos....");
            }
        }

FinDelCódigo 

Importante Anotaciones sobre ADO.NET Usadas en la Clase CDatos

ADO.NET

Es un conjunto de clases que exponen servicios de acceso a datos para el programador de .NET. ADO.NET ofrece abundancia de componentes para la creación de aplicaciones de uso compartido de datos distribuidas. Constituye una parte integral de .NET Framework y proporciona acceso a datos relacionales, XML y de aplicaciones. ADO.NET satisface diversas necesidades de desarrollo, como la creación de clientes de base de datos de aplicaciones para usuario y objetos empresariales de nivel medio que utilizan aplicaciones, herramientas, lenguajes o exploradores de Internet.

Algunas Clases de ADO NET

SqlConnection (Clase)

Su espacio de nombres es System.Data.SqlClient, representa una conexión abierta con una base de datos de SQL Server. Esta clase no se puede heredar.

Un objeto SqlConnection representa una única sesión con un origen de datos de SQL Server. Con un sistema de bases de datos de cliente y servidor, equivale a una conexión de red al servidor. SqlConnection se utiliza junto con SqlDataAdapter y SqlCommand para aumentar el rendimiento de la conexión a una base de datos de Microsoft SQL Server.

SqlDataAdapter (Clase)

Pertenece al espacio de nombres System.Data.SqlClient, representa un conjunto de comandos de datos y una conexión de base de datos que se utilizan para rellenar un DataSet y actualizar una base de datos de SQL Server. Esta clase no se puede heredar.

SqlDataAdapter, se utiliza como un puente entre DataSet y SQL Server para recuperar y guardar datos. SqlDataAdapter proporciona este puente mediante la asignación de Fill, que cambia los datos en DataSet para que coincidan con los datos del origen de datos; y Update, que cambia los datos en el origen de datos para que coincidan con los datos en DataSet utilizando las instrucciones de Transact-SQL en el origen de datos adecuado.