Gracias a Linq, vamos a poder realizar consultas a fuentes de datos de forma fácil y sencilla obteniendo como resultado tipos anónimos o entidades de negocio generadas por nosotros. En este post vamos a ver un ejemplo de Linq To Xml donde por medio de Linq vamos a obtener una colección que bindaremos a un repeater.
Una vez introducido el post vamos a la faena, primero necesitamos un xml que vamos a cargar con XElement que es una nueva clase perteneciente a System.Xml.Linq que nos permite operar de una forma sencilla con los xmls.
El xml que vamos a usar tiene el siguiente aspecto:
<?xml version="1.0" encoding="utf-8" ?>
<LinkList>
<Link>
<Text>
<![CDATA[Así se fundo Carnaby Street]]>
</Text>
<Title>
<![CDATA[Así se fundo Carnaby Street]]>
</Title>
<HRef>
<![CDATA[http://carnabys.blogspot.com/]]>
</HRef>
</Link>
<Link>
<Text>
<![CDATA[Búscate un novio]]>
</Text>
<Title>
<![CDATA[Búscate un novio]]>
</Title>
<HRef>
<![CDATA[http://buscateunnovio.blogspot.com/]]>
</HRef>
</Link>
<Link>
<Text>
<![CDATA[El blog de la nadadora]]>
</Text>
<Title>
<![CDATA[El blog de la nadadora]]>
</Title>
<HRef>
<![CDATA[http://lanadadora.blogspot.com/]]>
</HRef>
</Link>
</LinkList>
Una vez tenemos el xml, vamos a necesitar cargarlo. Como he dicho antes usaremos la clase XElement, esta tiene un metodo estático llamado Load que recibiendo el path del archivo lo carga y lo devuelve en un XElement. Sería algo así:
XElement xmlData = XElement.Load(string.Format("{0}{1}", HttpContext.Current.Request.PhysicalApplicationPath, XML_DATA_PATH));
Bien, pues ahora tambien tenemos cargado el xml y solo nos queda usar Linq para seleccionar los datos necesarios. De momento vamos a usar tipos anónimos y el código necesario sería:
var links = from node in xmlData.Descendants("Link")
select new
{
Text = node.Elements("Text").First().Value,
Title = node.Elements("Title").First().Value,
HRef = node.Elements("Href").First().Value
};
Como vemos en el código anterior, cuando definimos un elemento con var estamos indicando que va a ser un tipo anónimo, asi podemos crearlo implicitamente en el momento de su uso. Con from node in xmlData.Descendants([nodo a buscar]) select new, estamos indicando que por cada elemento que encuentre dentro de la colección origen, nos cree un tipo anónimo.
¿Como trabajar con entidades de negocio en lugar de tipos anónimos?
Como vamos a ver a continuación trabajar con entidades de negocio obtenidas gracías a Linq es tan sencillo como lo que hemos visto hasta ahora, no obstante antes de seguir vamos a crear la susodicha entidad con la que vamos a trabajar.
Esta va a ser muy sencilla y la vamos a llamar LinkInfo, va a tener 3 miebros, 3 propiedades y un constructor sobrecargado. La entidad tiene este aspecto:
public class LinkInfo
{
#region members
private string _text;
private string _title;
private string _href;
#endregion
#region properties
public string Text
{
get { return _text; }
set { _text = value; }
}
public string Title
{
get { return _title; }
set { _title = value; }
}
public string HRef
{
get { return _href; }
set { _href = value; }
}
#endregion
#region constructor
public LinkInfo() { }
public LinkInfo(string text, string title, string href)
{
_text = text;
_title = title;
_href = href;
}
#endregion
}
Una vez tenemos la entidad, la query que obtendra la información será la siguiente:
IEnumerable<LinkInfo> links = from node in xmlData.Descendants("Link")
select new LinkInfo
{
Text = node.Elements("Text").First().Value,
Title = node.Elements("Title").First().Value,
HRef = node.Elements("HRef").First().Value
};
Como podemos ver, la única diferencia entre trabajar con tipos anónimos y trabajar con una entidad, al final es que si trabajamos con la entidad tenemos que indicarlo es decir cuando hace el new hay que decirle de que es y por supuesto el contenedor de esa información tendra que ser un IEnumerable.
Como dice el título del post, al final esta info la tenemos que bindar a un repeater, asi que por último, ya solo nos falta añadir el repeater, implementar el ItemDataBound del mismo y hacer el binding. El repeater tendría este aspecto:
<asp:Repeater ID="rptrLinks" runat="server" OnItemDataBound="RptrLinks_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<a id="a" runat="server"></a>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Con implementar el itemDataBound, vamos a conseguir que se levante un evento por cada item de la colección que vamos a bindar, en el accederemos a esa información y la mapearemos con los controles de servidor:
protected void RptrLinks_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
LinkInfo l = (LinkInfo)e.Item.DataItem;
((HtmlAnchor)e.Item.FindControl("a")).InnerText = l.Text;
((HtmlAnchor)e.Item.FindControl("a")).Title = l.Title;
((HtmlAnchor)e.Item.FindControl("a")).HRef = l.HRef;
}
}
Y ahora con hacer el binding, pues ya estaría acabado el ejemplo. El binding lo realizamos así:
rptrLinks.DataSource =
links
;
rptrLinks.DataBind();
Y nada más por hoy. Como veis, es bastante sencillo Scott Guthrie en su blog tiene un post en el que crea un lector rss de una forma parecida. Espero que haya quedado lo sufientemente claro. Si no es así, respondere gustoso a vuestras dudas.
Y tras la petición popular, aqui os dejo el código.
Enlaces relacionados:
¿Que son los tipos anónimos? « a deshoras
Ejemplo practico: Mostrando el horóscopo desde una fuente externa con HttpWebRequest, HttpWebResponse, Linq y Ajax « a deshoras
Ejemplo práctico: Creando Unit Test para probar nuestro código « a deshoras
¿Puedes subir el código fuente del ejemplo?
Hecho!!!
ya puedes descargar el código.
Salud camarada!!!
Muy amable…
Novedades de .net 3.5. Creación de objetos más rapida con constructores anónimos « a deshoras