Linq es muy bueno y casi una de las mejores cosas que ha hecho la gente de Redmon para los desarrolladores aqui voy a intentar mostrar algo de lo que podemos hacer con Linq para leer archivos XML
Para poder utilizar Linq sobre archivos XML tenemosque anhadir el namespace «System.Xml.Linq» a nuestra clase con eso podemos habrir archivos xml de esta manera:
XDocument categoriasxml = XDocument.Load(Application.StartupPath+»\\categorias.xml«);
En el ejemplo asumo que existe un archivo llamado «categorias.xml» en laruta desde donde se ejecuta la aplicacion y lo cargo a un objeto de clase XDocument. En este caso la definicion de mi xml es la siguiente:
<?xml version=»1.0″ encoding=»utf-8″?>
<Categorias>
<categoria>
<id>1</id>
<nombre>Hoteleros</nombre>
</categoria>
<categoria>
<id>2</id>
<nombre>Programadores</nombre>
</categoria>
<categoria>
<id>3</id>
<nombre>gasfiteros</nombre>
</categoria>
<categoria>
<id>4</id>
<nombre>Otros</nombre>
</categoria>
</Categorias>
Ahora la idea es cagar esos datos directamente a una variabe que salga de Linq para eso aplico lo siguiente:
var categoriaslinq = from cates1 in categoriasxml.Descendants(«categoria»)
select new { id = cates1.Element(«id»).Value, nombre = cates1.Element(«nombre»).Value };
Como ven una sentencia de Linq tiene diferentes partes y aun que es muy similar a T-Sql tambien tiene sus diferencias, primero hay que decirle el origen en este caso de los elementos del archivo xml solo voy a tratar los que esten marcados con «categorias» y luego sigue la sentecia «select new » es aqui donde voy definiendo los campos y los nombres de los mismos en el equivalente a T-Sql seria el «as» cuando se fine un campo, en mi ejemplo seria: id = cates1.Element(«id»).Value como ven se tiene que usar la variable que se define en el «from» que es un objeto de la clase XElement y se le va diciendo que valor de las propiedades del xml se asigna al campo, en este caso «id».
En este caso al ejecutar esta linea tendriamos cargado en la variable «categoriaslinq» todos los valores que contenga el archivo xml.
Voy a explayarme algo mas en su suso pero con alguna vision de hacer una agenda que tome como datos dos archivos xml, primero las deficiones de clases, voy a tener dos clases basicas: Catalogos y Agendados sus deficiones son:
namespace agenda
{
public class categorias
{
int id;
public int Id
{
get { return id; }
set { id = value; }
}
string nombre;
public string Nombre
{
get { return nombre; }
set { nombre = value; }
}
public categorias()
{
id = 0;
nombre = "";
}
public categorias(int _id,string _nombre)
{
id = _id;
nombre = _nombre;
}
}
}
namespace agenda
{
public class agendados
{
int id;
public int Id
{
get { return id; }
set { id = value; }
}
int id_cat;
public int Id_cat
{
get { return id_cat; }
set { id_cat = value; }
}
string nombre;
public string Nombre
{
get { return nombre; }
set { nombre = value; }
}
string direccion;
public string Direccion
{
get { return direccion; }
set { direccion = value; }
}
string telfijo;
public string Telfijo
{
get { return telfijo; }
set { telfijo = value; }
}
string telmovil;
public string Telmovil
{
get { return telmovil; }
set { telmovil = value; }
}
string comentario;
public string Comentario
{
get { return comentario; }
set { comentario = value; }
}
public agendados()
{
id = 0;
id_cat = 0;
nombre = "";
direccion = "";
telfijo = "";
telmovil = "";
comentario = "";
}
public agendados(int _id, int _id_cat, string _nombre, string _direccion, string _telfijo, string _telmovil, string _comentario)
{
id = _id;
id_cat = _id_cat;
nombre = _nombre;
direccion = _direccion;
telfijo = _telfijo;
telmovil = _telmovil;
comentario = _comentario;
}
}
}
Ahora veremos que si tubieramos los datos cargados en listas tipadas tendriamos dos variables una llamada agends y otra a la que he llamado cates1, cada una es definica de esta manera:
List<categorias> cates;
List<agendados> agends;
En ellas he puesto el contenido de de los XML, de lo siguiente no estoy muy seguro de como hacerlo directamente desde Linq pero lo que hice es que una vez cargados los datos en nuestra variable Linq (recuerden la primera parte donde definia categoriaslinq) pues de alli hago un foreach y lo cargo a mi lista tipada en el caso de cates1 seria de esta manera:
foreach (var categori in categoriaslinq)
{
cates.Add(new categorias(Convert.ToInt16(categori.id), categori.nombre.ToString()));
}
Bueno digamos que ya cargue los valores de mis dos archivos en mis listas tipadas pero ahora lo que quiero es que en lugar de mostrarme el valor del id de categorias en mi lista me genere una lista nueva y mediante linq yo pueda hacer un join al estilo T-Sql pues aqui vien la magia de Linq y despues de eso tambien quiero que ese resultado vaya a parar a un datagridview, pues bien aqui lo tenemos:
var resultado = from datos in agends
join cates1 in cates
on datos.Id_cat equals cates1.Id
orderby cates1.Nombre, datos.Nombre
select new
{
Nombre=datos.Nombre,
Categoria = cates1.Nombre,
Direccion = datos.Direccion,
Telefono = datos.Telfijo,
Movil = datos.Telmovil,
Comentario = datos.Comentario,
Id = datos.Id,
Id_cat = datos.Id_cat
};
dataGridView1.DataSource = resultado.ToList();
dataGridView1.Columns[«Id»].Visible = false;
dataGridView1.Columns[«Id_cat»].Visible = false;
Mucha magia no hay y muy poco de oculto existe en esto puedes ver un «join» y bueno en vez de «=» hay «equals» y tambien un «order by» y bueno el «select» con los nombres que corresponden a cada uno de los elementos, con eso ya tienes en una variable esa respuesta, pero como es Linq, no se puede enlazar como origen de datos de una datagridview, pero podriamos convertirlo en lista y punto, para lo que podemos usar el metodo «ToList» que convierte a lista y ya esta.
Algo mas complicado seria filtrar esa consulta de forma tal que podamos mostrar solo los que corresponde a una sola categoria para ello podemos usar el siguente codigo de linq:
var resultado = from datos in agends
join cates1 in cates
on datos.Id_cat equals cates1.Id
where datos.Id_cat==cat
orderby cates1.Nombre, datos.Nombre
select new
{
Nombre = datos.Nombre,
Categoria = cates1.Nombre,
Direccion = datos.Direccion,
Telefono = datos.Telfijo,
Movil = datos.Telmovil,
Comentario = datos.Comentario,
Id = datos.Id,
Id_cat = datos.Id_cat
};
pue espero que hasta aqui ya tienen mas que suficiente como para que trabajen un rato con Linq.
ok, bienn dicho