You are on page 1of 7

Entendiendo ADO .

NET con C#,Mono y PostgreSQL (II)


por Martin Mrquez <xomalli@gmail.com> Introduccin ADO .Net es el modelo de la plataforma .NET que sirve para trabajar con diferentes fuentes de datos: bases de datos relacionales, documentos XML, documentos excel, etc. Ests fuentes de datos podemos encontrarlas en 2 tipos de ambientes, el primero y el ms comn es el ambiente conectado, donde los usuarios estn todo el tiempo consultando o modificando en tiempo real la informacin, y el otro es el ambiente desconectado donde es posible con las clases de .NET copiar una parte de los datos y modificarlos de manera aislada y sin conexin para despus regresar los cambios a la fuente de datos de donde fueron tomados.

Representacin de la base de datos en memoria con la clase DataSet

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; using System.Data;

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:

Usar el DataSet con datos desde un archivo XML

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#.

using using using using

Gtk; System; System.Data; System.IO;

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.

Usando la clase DataAdapter para traer datos desde PostgreSQL

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

en sistemas operativos distintos de

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

You might also like