Crear un Dataset Programaticamente


Esta vez les voy a mostrar como crea un dataset programaticamente, esto significa que posea múltiples tablas que estén relacionas entre sí, sería como crear una base de datos dentro del dataset pero desde codigo, es un proceso relativamente fácil, pero que a su vez es un tanto largo.
Para poder realizar esto deberás de tener lo siguiente:
- SQL Server 2005/08
- VS 2005/08/10
Como siempre comenzamos creando la base de datos dentro del servidor de base de datos, en nuestro caso en mi caso el sql server 2005, como es una base de datos relativamente grande les voy a dejar adjunto al código el script de creación de la base de datos, pero por si acaso les voy a dejar un captura del esquema de la base de datos:
Ya con la base de datos creada, procedemos a abrir nuestro vs y creamos un nuevo proyecto de C#, ya con el proyecto creado, modificamos el formulario para que nos quede de la siguiente manera:

Ya con el formulario procedemos a agregar una clase nueva a nuestro proyecto, que le daremos el nombre de operación. Esta clase será la encargada de interactuar con la base de datos, de esta manera dividimos en dos capas nuestro programa, una capa ocupada de la interfaz del usuario y otra ocupada del acceso a datos, hacer esta división nos ayuda a hacer programas más robustos y mantenibles.
En la nueva clase definimos los siguientes atributos:
private DataSet bdl;
private SqlDataAdapter adaptador;
private SqlConnection conn;
private SqlCommand comando;
private DataTable cliente;
private DataTable alquiler;
private DataTable empleado;
private DataTable sucursal;
private DataTable ejemplar;
private DataTable categoria;
private DataTable video;
private DataTable formato;
Como pueden ver hemos definido todas las tablas que existen en nuestra base de datos, ademas hemos definido otros objetos que nos ayudaran a realizar el intercambio de datos con el DBMS.
Ahora el constructor de la clase lo dejamos de la siguiente manera:
public operacion()
{
bdl = new DataSet("Base Datos Video Club");
conn = new SqlConnection("Database=BDVIDEOCLUB;Data Source=192.168.18.128;User Id=sa;Password=sa");
comando = new SqlCommand(@"Select * from formato;
SELECT * from categoria;
Select * from video;
Select * from sucursal;
Select * from empleado;
Select * from cliente;
Select * from ejemplar;
Select * from alquiler;", conn);
adaptador = new SqlDataAdapter(comando);
creacionTablas();
}
En el constructor de esta clase lo que hacemos es instanciar todos los objetos encargados de interactuar con el DBMS, ademas de que llamamos al metodo “creacionTablas”, este metodo sera el que se encargue de crear las tablas que estaran dentro del datset, este metodo queda asi:
//======================================================================================
//========================= Tabla Cliente ==============================================
//======================================================================================
cliente = new DataTable("Cliente");
DataColumnCollection cols = cliente.Columns;//Se crea una coleccion de columnas para hacer mas comodo el trabajar con estas
DataColumn col = cols.Add("COD", typeof(System.Int32));//Se crea la llave primaria
col.AutoIncrement = true;//Se le indica que debe de existir auto incremento
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
//Se crean los campos restantes
cols.Add("CI", typeof(System.Int32));
cols.Add("Apellido", typeof(System.String)).MaxLength = 35;
cols.Add("Nombre", typeof(System.String)).MaxLength = 35;
cols.Add("Telefono", typeof(System.Int32));
//cols.Add("CLI_COD", typeof(System.Int32));//NO se entiende el hecho de la autorelacion
cliente.PrimaryKey = new DataColumn[] { cols["COD"] };
bdl.Tables.Add(cliente);
//======================================================================================
//========================= Tabla Sucursal ==============================================
//======================================================================================
sucursal = new DataTable("Sucursal");
cols = sucursal.Columns;
col = cols.Add("COD", typeof(System.Int32));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
//Se crean los campos restantes
cols.Add("Descr", typeof(String)).MaxLength=255;
cols.Add("Telefono", typeof(Int32));
cols.Add("Direccion", typeof(String)).MaxLength = 255;
sucursal.PrimaryKey= new DataColumn []{ cols["COD"]};
bdl.Tables.Add(sucursal);
//======================================================================================
//========================= Tabla Categoria ==============================================
//======================================================================================
categoria = new DataTable("Categoria");
cols = categoria.Columns;
col = cols.Add("COD", typeof(Int32));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
//Se crean los campos restantes
cols.Add("Descr", typeof(String));
categoria.PrimaryKey = new DataColumn[] { cols["COD"] };
bdl.Tables.Add(categoria);
//======================================================================================
//========================= Tabla Formato ==============================================
//======================================================================================
formato = new DataTable("Formato");
cols = formato.Columns;
col = cols.Add("COD", typeof(Int32));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
//Se crean los campos restantes
cols.Add("Descr", typeof(String));
formato.PrimaryKey = new DataColumn[] { cols["COD"] };
bdl.Tables.Add(formato);
//======================================================================================
//========================= Tabla Video ==============================================
//======================================================================================
video = new DataTable("Video");
cols = video.Columns;
col = cols.Add("COD", typeof(Int32));
col.AutoIncrement = true;
col.AutoIncrementStep = -1;
col.AutoIncrementSeed = -1;
//Se crean los campos restantes
cols.Add("Descr", typeof(String)).MaxLength=255;
cols.Add("Cat_Cod", typeof(Int32));
video.PrimaryKey=new DataColumn[] { cols["COD"] };
bdl.Tables.Add(video);
//======================================================================================
//========================= Tabla Ejemplar ==============================================
//======================================================================================
ejemplar = new DataTable("Ejemplar");
cols = ejemplar.Columns;
col = cols.Add("COD", typeof(Int32));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
//Se crean los campos restantes
cols.Add("Descr", typeof(String));
cols.Add("Vid_Cod", typeof(Int32));
cols.Add("For_Cod", typeof(Int32));
ejemplar.PrimaryKey = new DataColumn[] { cols["COD"] };
bdl.Tables.Add(ejemplar);
//======================================================================================
//========================= Tabla Empleado ==============================================
//======================================================================================
empleado = new DataTable("Empleado");
cols = empleado.Columns;
col = cols.Add("COD", typeof(Int32));
col.AutoIncrement = true;
col.AutoIncrementSeed = -1;
col.AutoIncrementStep = -1;
cols.Add("Apellido", typeof(String)).MaxLength = 50;
cols.Add("Nombre", typeof(String)).MaxLength = 50;
cols.Add("Salario", typeof(float));
cols.Add("FechaNac", typeof(DateTime));
cols.Add("LugarNac", typeof(String));
cols.Add("Suc_Cod", typeof(Int32));
empleado.PrimaryKey = new DataColumn[] { cols["COD"] };
bdl.Tables.Add(empleado);
//======================================================================================
//========================= Tabla Alquiler ==============================================
//======================================================================================
alquiler = new DataTable("Alquiler");
cols = alquiler.Columns;
cols.Add("Fecha", typeof(DateTime));
cols.Add("Cli_Cod", typeof(Int32));
cols.Add("Eje_Cod", typeof(Int32));
cols.Add("Emp_Cod", typeof(Int32));
alquiler.PrimaryKey = new DataColumn[] { cols["Fecha"], cols["Cli_Cod"], cols["Eje_Cod"] };
bdl.Tables.Add(alquiler);
//======================================================================================
//========================= Creacion de Relaciones ==============================================
//======================================================================================
bdl.Relations.Add("Sucursal_Empleado", sucursal.Columns["COD"], empleado.Columns["Suc_Cod"]);
bdl.Relations.Add("Formato_Ejemplar", formato.Columns["COD"], ejemplar.Columns["For_Cod"]);
bdl.Relations.Add("Categoria_Video", categoria.Columns["COD"], video.Columns["Cat_Cod"]);
bdl.Relations.Add("Video_Ejemplar", video.Columns["COD"], ejemplar.Columns["Vid_Cod"]);
bdl.Relations.Add("Empleado_Alquiler", empleado.Columns["COD"], alquiler.Columns["Emp_Cod"]);
bdl.Relations.Add("Ejemplar_Alquiler", ejemplar.Columns["COD"], alquiler.Columns["Eje_Cod"]);
bdl.Relations.Add("Cliente_Alquiler", cliente.Columns["COD"], alquiler.Columns["Cli_Cod"]);
//======================================================================================
//========================= Creacion del Mapa de Tablas ==============================================
//======================================================================================
adaptador.TableMappings.Add("Table", "Formato");
adaptador.TableMappings.Add("Table1", "Categoria");
adaptador.TableMappings.Add("Table2", "Video");
adaptador.TableMappings.Add("Table3", "Sucursal");
adaptador.TableMappings.Add("Table4", "Empleado");
adaptador.TableMappings.Add("Table5", "Cliente");
adaptador.TableMappings.Add("Table6", "Ejemplar");
adaptador.TableMappings.Add("Table7", "Alquiler");
}
Como se puede leer en los comentarios , lo primero que se hace es instanciar la tabla, luego se procede a crear una colección de columnas, el hacer esto nos facilita el manejo de las columnas de la tabla, despues procedemos a agregar la columna correspondiente la llave primaria, a su vez esta se asigna a una varible llamada “col” del tipo DataColumn, esto al igual que la colección de columnas lo hago por comodida , luego a este campo le indicamos que debe de autoincrementarse, con una semilla de autoincremento de -1 y un paso de incremento de -1, terminado esto procedemos a agregar el resto de campos de la tablas, incluida llaves foraneas, con esto estaria nuestra tabla creada, por lo cual ya puede ser agregada al dataset.
Luego de haber creado todas las tablas y haberlas agregado al dataSet, se procede a crear las relaciones entre estas, para hacerlo debemos agregar estas desde el metodo .Relation.Add() que posee el dataset, el ,primer parametro que debemos enviarle es el nombre que deseamos que posea nuestra relacion, el segundo parametro corresponde a la llave primaria de la tabla padre y el tercer parametro corresponde al campo de la llave foranea de la tabla hija.
Con todo lo que hicimos hasta ahora ya tenemos toda la base de datos dentro del dataset, pero si lo pusieramos a prueba no nos fucionaria adecuadamente ya que aun nos falta el mapeo de las tablas, esto se lo realiza en el DataAdapter, lo que hace el mapeo de las tablas es asignar las tablas que se obtienen del DBMS a las tablas ya creada dentro del DataSet, esta operación se la realiza a traves del metodo .TableMappings.Add(), el primer parametro corresponde al nombre de la tabla recibida y el segundo al nombre de la tabla a la que se asignara la primera, como apunte importante observen la relacion que existe entre el orden de agregacion de las tablas y el orden de las consultas Select del DataAdapter (en el constructor), si no se tuviera ese orden, se producirira una excepcion del tipo DataException por que como creamos relaciones entre las tablas, si se intenta llenar una tabla hija sin que exista la tabla padre con sus repectivas llaves primarias habria un problema con la integridad de datos.
Ya con el DataSet terminado, procedemos a llenarlo con datos y lo hacemos con el siguiente metodo:
public void update()
{
try
{
adaptador.Fill(bdl);
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
catch (DataException ex)
{
MessageBox.Show(ex.Message);
}
catch( SystemException ex)
{
MessageBox.Show(ex.Message);
}
}
Lo unico que se hace en este metodo es ejecutar el metodo Fill del DataAdapter dentro de un boque Try-Catch, que si en caso de que existiera una exception, este lo atraparia.
Ahora para visualizar los datos en un DataGridView, lo que hacemos es crear el metodo publico llenado(), que recibe como parametros un DataGridView y el nombre de la tabla que se desea mostrar:
public void llenado(DataGridView dgw, String tabla)
{
update();
dgw.DataSource = bdl.Tables[tabla];
}
Ahora para poder visualizar los datos, nos dirigimos al formulario, ahí definimos una varible del tipo Operación, luego nos dirigimos al metodo asociado al evento click del boton mostrar y ahí lo unico que hacemos es llamar al metodo llenado del objeto del tipo Operación, elcodigo del formulario deberia de quedar asi:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
op = new operacion();
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
op.llenado(dataGridView1, comboBox1.Text);
}
private operacion op;
}
Con todo esto hecho ya podemos proceder a probar el programa, si todo lo hicimos correctamente tendriamos algo asi:

Creo que con todo hasta aquí esta mas que demostrado como se hace y como funciona el creado de un dataSet complejo y que con esto esta acabado este post, pero como se que ustedes son muy observadores y se que me diran, para que sirve el groupBox “Video” ya que hasta ahora no hiciste nada hasta ahora con el y pues les diria que sirve para agregar nuevos registros a la tabla video y de esta menera mostrar una ventaja de hacer esto del programado del DataSet.
Entonces comencemos con esa parte, primero nos dirigimos a la clase Operación y crear el metodo nuevo registro que reciba como argumentos una String y un int, despue dentro del metodo debemos proceder a agregar el registro a la tabla video a traves del campo. Rows.Add(), el metodo deberia de quedar asi:
public void nuevoRegistro(String descr, int cat_cod)
{
try
{
bdl.Tables["Video"].Rows.Add(new object[] { null, descr, cat_cod });
}
catch (DataException ex)
{
MessageBox.Show(ex.Message, "Error agregando nueva fila");
}
}
Como siempre vemos que toda operación que realicemos que implique la manipulacion de datos de un dataSet debe de estar enmarcado en un bloque Try-Catch.
Por ultimo debemos de irnos al formulario y en el metodo asociado al evento del boton gurdar debemos de llamar al metodo nuevo registro.
Si todo nos salio bien deberiamos de tener algo asi:

Como pueden ver, el programa esta controlando la integridad de datos sin problemas lo cual nos favorece durante el desarrollo de aplicaciones y ademas nos da una mejor vision de cómo funciona ADO.Net en su modo desconectado.
Bueno me despido esperando que les haya servido el post
Bye!

2 comentarios

No me quedó claro dónde tengo que introducir el código de las tablas TABLA CLIENTE, TABLA SUCURSAL, etc??.
Ojala que para próximas versiones del VS ya se pueda pasar todo un modelado de db incluida sus relaciones... sería más fácil.
Saludos.

Reply

Hola, lo campos del tipo CODIGO son autogenerados por la Base de Datos. Ahora lo que deseas de pasar un modelo de BD a Codigo, puedes usar Entity Framework, a traves del patron DB First.

Reply

Publicar un comentario