sábado, 1 de marzo de 2008

LinQ to Object


LinQ to Sql (Arquitectura de capas):


Ahora vamos a ver el comportamiento funcional de LinQ to Object, este permite realizar cualquier tipo de búsqueda en los tipos de objetos que se manejan en la definición del framework 3.5, podemos realizar acciones de búsqueda sobre arreglos de una o más dimenciones, para rescatar datos en específico o, podemos realizar búsquedas sobre listas, ya que realizaremos modificaciones sobre listas de clases de objetos.

Como vimos, en los ejemplos de LINQ TO SQL, lo que haciamos hera retornar listas que tenían estructuras de clases, ahora lo que haremos, será, tomar estas listas de datos y realizar acciones sobre estas.

Este ejemplo no se conectará a Base de Datos para traer la información, sino más bien, vamos a crear nuestra lista y realizaremos acciones sobre esta, para ello debemos crear la siguiente interfaz:


Los controles los he nombreado de la siguiente forma (ustedes pueden distribuirlos y nombrarlos como quieran):

  • txtNombre TextBox
  • txtApellidoPaterno TextBox
  • txtApellidoMaterno TextBox
  • txtFechaNacimiento TextBox
  • lblNombre Label
  • lblApellidoMaterno Label
  • lblApellidoPaterno Label
  • lblFechaNacimiento Label
  • btnAgregar Button
  • btnBuscar Button
  • Edad Label
  • label2 Label
  • txtEdad TextBox
  • txtNombreBusqueda TextBox
  • lvwPersona ListView
  • btnBusqueda2 Button

Comentemos el ejemplo, bueno, lo que haremos será crear una lista en la cual buscaremos información de una persona según su edad (Este ejemplo está basado en uno de los que Microsoft a lanzado para Visual Basic este año).

Para ello debemos agregar usuarios a la lista, desplegar los mismos y, realizar las búsquedas de estos por el o los criterios definidos, entonces vamos a ello:

primero crearemos en el mismo archivo del formulario, pero fuera del estacio de nombre de clase de formulario, pero dentro del namespace la siguiente clase:


public class clsPersona
{
private string _strNombre;
private string _strApellidoPaterno;
private string _strApellidoMaterno;
private DateTime _fcFechaNacimiento;
public string Nombre{
get { return _strNombre; }
set { _strNombre = value; }
}
public string ApellidoPrimero{
get { return _strApellidoPaterno; }
set { _strApellidoPaterno = value; }
}
public string ApellidoSegundo{
get { return _strApellidoMaterno; }
set { _strApellidoMaterno = value; }
}
public DateTime FechaNacimiento{
get { return _fcFechaNacimiento; }
set { _fcFechaNacimiento = value; }
}
public int Edad{
get{
try{
DateTime iDia = DateTime.Now;
return (int)iDia.Subtract(FechaNacimiento).TotalDays / 365;
}
catch (Exception ex){throw ex;}
}
}
}

Si se observa lo que haremos será utilizar esta estructura para crear una lista, luego realizaremos una búsqueda se personas según su edad y, es aquí en donde la propiedad Edad() se torna importante.

Ahora crearemos dos funciones, las cuales cooperarán para agregar a la lista los nuevos registros de personas.

1 - En el espacio de nombre de la clase del formulario que han creado definiremos la siguiente variable de lista:


List lstPersona = new List { };

2 - En el método que atiende el evento click del botón btnAgregar definiremos las siguientes líneas de código:


private void btnAgregar_Click(object sender, EventArgs e) {
try {

// creamos el nuevo registro y lo agregamos a la lista
clsPersona cls = new clsPersona();
cls.Nombre = this.txtNombre.Text;
cls.ApellidoPrimero = this.txtApellidoPaterno.Text;
cls.ApellidoSegundo = this.txtApellidoMaterno.Text;
cls.FechaNacimiento = DateTime.Parse(this.txtFechaNacimiento.Text);
this.lstPersona.Add(cls);

// desplegamos la información de la lista
this.prcCrearColumna();
string[] reg = new string[4];
int num = this.lstPersona.Count();

for (int i = 0; i <>reg[0] = this.lstPersona[i].Nombre.ToString();
reg[1] = this.lstPersona[i].ApellidoPrimero.ToString() + " " +
this.lstPersona[i].ApellidoSegundo.ToString();
reg[2] = this.lstPersona[i].FechaNacimiento.ToString("dd/MM/yyyy");
reg[3] = this.lstPersona[i].Edad.ToString();

ListViewItem lvi = new ListViewItem(reg);
this.lvwPersona.Items.Add(lvi);
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}

Ahora como estamos trabajando con un listview debemos crear las columnas, para ello y, por que se está llamando desde la función anterior crearemos el siguiente método:

private void prcCrearColumna() {
try {
this.lvwPersona.Clear();
this.lvwPersona.View = View.Details;
this.lvwPersona.Columns.Add("Nombre", 150, HorizontalAlignment.Left);
this.lvwPersona.Columns.Add("Apellidos", 200, HorizontalAlignment.Left);
this.lvwPersona.Columns.Add("Fecha Nacimiento", 200, HorizontalAlignment.Left);
this.lvwPersona.Columns.Add("Edad", 50, HorizontalAlignment.Left);
}
catch (Exception ex) { throw ex; }
}

Bueno, ya tenemos definida la lógica para gregar registros de personas a la lista, ahora lo que debemos hacer es definir el criterio de búsqueda dentro del objeto de lista que hemos creado, para ello y como según definimos en los botones de búsqueda definiremos dos tipos de búsuqueda: simple y formateada.

3 - Busqueda y despliegue de datos de forma simple.

En la búsqueda simple lo que haremos será rescatar la información, según el criterio definido y desplegarlo en pantalla mediante un messagebox, esto se hará en el método que atiende el evento click del boton btnBuscar y, las líneas de código se observan a continuación:


private void btnBuscar_Click(object sender, EventArgs e) {
try {
int edad = (txtEdad.Text != "") ? int.Parse(txtEdad.Text) : 0;
string nombre = (txtNombreBusqueda.Text != "") ? txtNombreBusqueda.Text : "";

var qry = from p in lstPersona
where (p.Edad > edad && p.Nombre.IndexOf(nombre) != -1)
orderby p.Nombre, p.ApellidoPrimero, p.ApellidoSegundo, p.FechaNacimiento, p.Edad
select p;

foreach (var p in qry){
string msg =
string.Format(" Nombre {0}\r\n Fecha de Nacimiento {1}\r\n Edad {2} años",
p.Nombre + " " + p.ApellidoPrimero + " " + p.ApellidoSegundo,
p.FechaNacimiento.ToString("dd/MM/yyyy"), p.Edad);

MessageBox.Show(msg);
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}

Bueno, que más decir, si comentamos el código nos centraremos en la lógica de búsqueda, en la cual se realizará la búsqueda dentro del objeto lstPersona segun nombre y la propiedad edad. La propiedad Edad tomará la fecha y calculará si el usuario cumple con la edad requerida y la coincidencia de nombre entregado.

Vean que cuando busco el nombre utilizo los métodos asociados a la clase string, es decir IndexOf, con esto podemos ver que las sentencias del lenguaje pueden perfectamente ponerse dentro de la clausula where.

Por ultimo, si existen más de un registro en la lista de estructura de clase, debemos desplegarlo, por eso he definido el despliegue en un foreach.

Cuando el tipo de dato no les funciones, lo mejor es asignar el recorrido del foreach a la clausula var

4 - Busqueda y despliegue de datos de forma formateada.

Bueno la direferencia que existe en la búsqueda simple es que sin crear un objeto de clase en el resultado de búsqueda como vimos en LinQ to Sql también podemos crear formatos de resultados abstractos creados en el resultado asignado. Para ver esto, en el método que atiende el evento click del botón btnBusqueda2, agregaremos las siguientes líneas de código:


private void btnBusqueda2_Click(object sender, EventArgs e) {
try {
int edad = (txtEdad.Text != "") ? int.Parse(txtEdad.Text) : 0;
string nombre = (txtNombreBusqueda.Text != "") ? txtNombreBusqueda.Text : "";

var qry = from p in lstPersona
where (p.Edad > edad && p.Nombre.IndexOf(nombre) != -1)
orderby p.Nombre, p.ApellidoPrimero, p.ApellidoSegundo, p.FechaNacimiento
select new {
NombreApellidos = string.Format("{0} {1} {2}",
p.Nombre, p.ApellidoPrimero,
p.ApellidoSegundo),
p.FechaNacimiento,
p.Edad
};

foreach (var p in qry) {
string msg = string.Format(" Nombre {0}\r\n Fecha de Nacimiento {1}\r\n Edad {2} años",
p.NombreApellidos, p.FechaNacimiento.ToString("dd/MM/yyyy"), p.Edad);
MessageBox.Show(msg);
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}

Comentemos el código: si se observa ahora estamos creando el formato de salida del resultado de la búsqueda en las siguientes líneas

var qry = from p in lstPersona
where (p.Edad > edad && p.Nombre.IndexOf(nombre) != -1)
orderby p.Nombre, p.ApellidoPrimero, p.ApellidoSegundo, p.FechaNacimiento
select new {
NombreApellidos =
string.Format("{0} {1} {2}", p.Nombre, p.ApellidoPrimero,p.ApellidoSegundo),
p.FechaNacimiento,
p.Edad };

Ahora la concatenación de datos se hace dentro del resultado, no he probado formatear la fecha, prueben, no deberían tener problemas.

Ahora a probar, suerte y saludos

No hay comentarios: