Professional Documents
Culture Documents
La clase DataSet es de las ms utilizadas en cuanto a los modelos de trabajo de ADO .NET,esta clase trabaja con datos sin una conexin permanente a la base de datos, en modo desconectado o igualmente trabaja en modo conectado junto a la clase DataAdapter. Un DataSet puede contener un esquema de base de datos (DataBaseSchema) en memoria con todos sus elementos como tablas, relaciones y reglas, cada uno de estos elementos estn representados por las siguientes clases:
DataTable: Representa una tabla de una base de datos, el DataSet puede contener una o una coleccin de objetos DataTable, y un DataTable contiene una o una coleccin de objetos DataRow. DataRelation: Este objeto relaciona dos o ms objetos DataTable que se encuentren dentro del DataSet, representa la relacin primary key/foreign key de 2 o ms tablas. DataRow: Representa una fila de datos del DataTable, en las consultas o actualizaciones, el DataSet trabaja con objetos DataRow. DataColumn: Representa una columna de datos en la DataTable, se trabaja con estos objetos cuando se crea o se modifica un DataTable. La clase Dataset es una clase totalmente genrica de ADO .NET por lo que no importa el proveedor especifico que se utilice para llenar de datos el DataSet, el DataSet siempre tendr el mismo comportamiento con distintas bases de datos.
Listado 2.1 Archivo MiDataSet.cs, clase para llenar un DataSet sin conexin a la base de datos.
using System.IO; namespace Godel.Listados { class MiDataSet { public static void Main(string[] args) { DataSet dsPubs = new DataSet("pubs"); DataTable dt = new DataTable("items"); DataColumn id = new DataColumn("id",Type.GetType("System.Int32")); id.AutoIncrement = true; dt.Columns.Add(id); dt.Columns.Add(new DataColumn("name",Type.GetType("System.String"))); DataRow oneRow = dt.NewRow(); oneRow["name"] = "Martin"; DataRow secondRow = dt.NewRow(); secondRow["name"] = "Bill"; dt.Rows.Add(oneRow); dt.Rows.Add(secondRow); dsPubs.Tables.Add(dt); Console.WriteLine("[ {0} ]",dsPubs.Tables[0].TableName); foreach(DataColumn dc in dsPubs.Tables[0].Columns){ Console.Write("\t|" + dc.ColumnName); } Console.Write("\n"); printRows(dsPubs.Tables[0]); } static void printRows(DataTable table){ int columns = table.Columns.Count; foreach(DataRow dr in table.Rows){ for(int i = 0;i < columns;i++){ Console.Write("\t|" + dr[i].ToString()); if(i == (columns - 1)) Console.Write("\n"); } } } } } Compilamos y ejecutamos el programa con: $ mcs -r:System.Data MiDataSet.cs $ mono MiDataSet.exe y al ejecutarlo se vera algo como la pantalla siguiente:
No es necesario indicarle al DataSet de que fuente provienen los datos puesto que el DataSet puede construirse con datos de cualquier base de datos relacional o desde archivos XML, ya que tiene mtodos para leer y escribir archivos XML.
Listado 2.2: Archivo registros.xml, donde el DataSet tomar los datos para llenarse.
<?xml version="1.0"?> <registros> <Authors> <au_id>3</au_id> <au_lname>Carson</au_lname> <au_fname>Cheryl</au_fname> <phone>415 548-7723</phone> <address>589 Darwin Ln.</address> <city>Berkeley</city> <state>CA</state> <zip>94705</zip> <contract>true</contract> </Authors> <Authors> <au_id>4</au_id> <au_lname>Ringer</au_lname> <au_fname>Albert</au_fname> <phone>801 826-0752</phone> <address>67 Seventh Av.</address> <city>Salt Lake City</city> <state>UT</state> <zip>84152</zip> <contract>true</contract> </Authors> </registros>
Listado 2.3 Archivo ReadXmlGtk.cs, Lee los registros del archivo XML y los muestra en una ventana GTK#.
namespace Godel.Listados { public class ReadXmlGtk : Window{ private Entry txtarchivo = new Entry(); private TreeView txtshow; private ListStore store; public ReadXmlGtk() : base("Ejercicio 2.3") //esto es solo el GUI {
BorderWidth = 8; this.DeleteEvent += new DeleteEventHandler(OnWindowDelete); Frame frame = new Frame ("Leer un archivo .xml"); Add (frame); VBox MainPanel = new VBox (false, 8); MainPanel.BorderWidth = 8; frame.Add (MainPanel); txtarchivo.IsEditable = false; MainPanel.PackStart (txtarchivo, false, false, 0); ScrolledWindow scrolledWindow = new ScrolledWindow (); scrolledWindow.ShadowType = ShadowType.EtchedIn; scrolledWindow.SetPolicy(PolicyType.Automatic, PolicyType.Automatic); store = CreateModel (); txtshow = new TreeView(store); scrolledWindow.Add (txtshow); MainPanel.PackStart (scrolledWindow, true, true, 0); AddColumns(txtshow); SetDefaultSize (320, 233); ShowAll (); } private void AddColumns (TreeView treeView) { CellRendererText rendererText = new CellRendererText (); string[] s = {"id","Apellido","Nombre","Telefono"}; TreeViewColumn column; for(int i = 0;i < s.Length;i++){ column = new TreeViewColumn (s[i], rendererText, "text", i); treeView.AppendColumn (column); } private ListStore CreateModel(){ ListStore store = new ListStore (typeof(string), typeof(string), typeof(string), typeof(string)); //verifica si existe el archivo XML if(File.Exists("registros.xml")){ FileInfo fi = new FileInfo("registros.xml"); txtarchivo.Text = fi.FullName; //se crea el dataset y se recorre la enumeracin DataSet ds = new DataSet(); ds.ReadXml(fi.FullName); foreach(DataRow dr in ds.Tables["Authors"].Rows) }
store.AppendValues(dr["au_id"],dr["au_lname"],dr["au_fname"],dr["phone"]); } } return store; } public void OnWindowDelete(object o, DeleteEventArgs args) { Application.Quit(); } } } Compilamos y ejecutamos el programa con: $ mcs -pkg:gtk-sharp-2.0 -r:System.Data $ mono ReadXmlGtk.exe Si no tenemos errores, se mostrar la siguiente imagen al ejecutarse. ReadXmlGtk.cs
Algo importante es que todos los cambios realizados en el DataSet existen solo en memoria y sern permanentes hasta que sean enviados hacia la base de datos usando la clase DataAdapter o hacia un archivo XML.
La clase DataAdapter es especifica de un proveedor para .NET en el caso de postgreSQL es NpgslDataAdapter, para SQL Server es SqlDataAdapter, para Oracle es OracleDataAdapter, etc. Esta clase contiene cuatro objetos Command: SelectCommand, UpdateCommand, InsertCommand y DeleteCommand y es el puente entre una conexin a una Base de Datos/ LDAP y un objeto DataSet. Se usa el SelectCommand para llenar un DataSet y los 3 comandos restantes para transmitir los cambios de nuevo en la fuente de datos, es importante tener en mente que sin el uso de DataAdapter los cambios realizados en el DataSet solo estarn vigentes en el DataSet y no en la fuente de datos de donde se tomaron,por eso siempre que se use un DataSet debe de usarse un DataAdapter para hacer los cambios en la base de datos o en nuestra fuente de informacin.
Listado 2.4: Archivo GtkAdapter.cs muestra el uso de DataAdapter para llenar el DataSet. using using using using using Gtk; System; Npgsql; System.Data; System.Text;
namespace Godel.Listados { public class GtkAdapter : Window { private TextView txtQuery = new TextView(); private TextView txtShow = new TextView(); private StringBuilder buf = new StringBuilder(); public GtkAdapter() : base("Listado 2.4"){ DeleteEvent += new DeleteEventHandler(ClosedWindowEvent); this.BorderWidth = 8; Frame frame = new Frame("Consulta a pubs en PostgreSQL"); this.Add (frame); VBox MainPanel = new VBox (false, 8); frame.Add (MainPanel); HBox hbox = new HBox (false,8); MainPanel.PackStart (hbox, false, false, 0); hbox.PackStart(TextArea(txtQuery),true,true,0);
SetDefaultSize(556,400); Button btnSubmit = new Button("Ejecutar consulta"); btnSubmit.Clicked += new EventHandler(btnSubmitClicked); MainPanel.PackStart(btnSubmit,false,false,0); MainPanel.PackStart(TextArea(txtShow),true,true,0); ShowAll(); } private ScrolledWindow TextArea(TextView textField){ ScrolledWindow sw = new ScrolledWindow(); textField.WrapMode = WrapMode.Char; sw.ShadowType = ShadowType.EtchedIn; sw.Add(textField); return sw; } void ClosedWindowEvent(object o, DeleteEventArgs args){ Application.Quit(); } void btnSubmitClicked(object o, EventArgs args){ TextBuffer bufQuery = txtQuery.Buffer; TextBuffer bufShow = txtShow.Buffer; NpgsqlConnection conn = new NpgsqlConnection(@"Server=127.0.0.1;Port=5432;User Id=postgres;Password=chikome;Database=pubs"); NpgsqlCommand cmd = conn.CreateCommand(); cmd.CommandText = bufQuery.Text; NpgsqlDataAdapter da = new NpgsqlDataAdapter(); da.SelectCommand = cmd; DataSet ds = new DataSet(); da.Fill(ds,"Results"); foreach(DataColumn dc in ds.Tables[0].Columns){ bufShow.Text += "\t" + dc.ColumnName; } bufShow.Text += "\n"; printRows(ds.Tables[0]); bufShow.Text += buf.ToString(); } private void printRows(DataTable table){ int columns = table.Columns.Count; foreach(DataRow dr in table.Rows){ for(int i = 0;i < columns;i++){ buf.Append("\t" + dr[i].ToString()); if(i == (columns - 1)) buf.Append("\n"); } } } [STAThread] public static void Main(string[] arg){ Application.Init(); new GtkAdapter(); Application.Run(); } } }
Compilamos y ejecutamos el programa con: $ mcs -r:System.Data,Npgsql -pkg:gtk-sharp-2.0 GtkAdapter.cs $ mono GtkAdapter.exe Si no tenemos errores, se mostrar la siguiente imagen al ejecutarse.
Conclusin
Este documento presenta algunas caractersticas elementales de las clases DataSet y DataAdapter que ADO .Net proporciona para facilitar el trabajo con datos de diferentes fuentes en diferentes escenarios,y como es posible trabajar con los beneficios de esta arquitectura Windows y mejor an en sistemas abiertos y libres. En la ltima parte de este tutorial explicar mediante ejemplos el resto de las capacidades de estos objetos. Todos los ejemplos de este documento pueden ser descargados de http://www.humansharp.com/index.php? var=code
Este documento est protegido bajo la licencia de documentacin libre Free Documentacion License del Proyecto GNU, para consulta ver el sitio
http://www.gnu.org/licenses/fdl.txt , toda persona que lo desee est autorizada a usar, copiar y modificar este documento segn los puntos establecidos en la Licencia FDL