LINQ y entidades de datos
LINQ
Language Integrated Query,
Lenguaje de consultas integrado
.net 3.5+
consultas a DataSources
sintaxis unica
Data source
DB -> SQL
XML -> XQuery
Arreglo/Colección -> Ciclos
¿Porque aprender diferentes sintaxis para diferentes tipos de datos?
¿Qué db podemos utilizar?
-
Windows Azure SQL Database
• Local Network SQL Server
• Local Machine SQL Server Express
• Application SQL LocalDB
• Application SQL CE
• Otros proveedores: Oracle, SqLite, MySql, DB2, Jet
¿Cómo funciona?
LINQ Workflow
Seguimiento a una consulta
Dos formas de hacer consultas en LINq:
EXPRESIONES DE CONSULTA
EXPRESIONES BASADAS EN METODOS
Expresiones de consulta
(Query Expressions)
parecidas a SQL
se convierten el Method-Base Expressions
Ejemplo de query expression
int[] datos = new int[]{1,2,3,4,5,6,7,8,9,10};
var pares = from i in datos where i % 2 == 0 select i;
Console.WriteLine("Los numeros pares son:"); foreach (int i in pares) Console.WriteLine(i);
from -> where -> select
tipo var
sintaxis parecida a SQL
consultas mas "simples"
Expresiones basadas en metodos
(Method-base Expressions)
uso de metodos
expresiones escritas usando lambda
consultas mas "complejas"
Ejemplo de method-base expression
int[] datos = new int[]{1,2,3,4,5,6,7,8,9,10}; var pares = datos.Where(x => x % 2 == 0).Select(x => x);
Console.WriteLine("Los numeros pares son:"); foreach (int i in pares) Console.WriteLine(i);
uso de metodos
from inexistente
contiene metodos
empresion lambda
consultas mas "complejas"
Funciones de agregación
agregan utilidades
-
average
-
sum
-
count
-
min
-
max
- count
forma de metodos
Ejemplo de la función de agregación count
Expresión de consulta
var pares = from i in datos
where i % 2 == 0
select i;
var totalPares = pares.Count();
Console.WriteLine("El total de numeros pares es: "+totalPares);
Expresión basada en metodos
var totalPares = datos.Where(x => x % 2 == 0).Select(x => x).Count();
Console.WriteLine("El total de numeros pares es: "+totalPares);
Colecciones genericas
.NET 2.0+
datos "fuertemente tipeados"
definido en declaración e instanciación
Colecciones genericas de .net
namespace System.Collections.Generic
- Dictionary<TKey, TValue>
-
HashSet<T>
-
LinkedList<T>
-
List<T>
-
Queue<T>
-
SortedDictionary<TKey, TValue>
-
Stack<T>
Ejemplo 1 de estructuras genericas
Stack<Libro> librosPorLeer = new Stack<Libro>();
Dictionary<int, Alumno> listaCurso = new Dictionary<int, Alumno>();
Stack<T>
Dictionary<TKey, TValue>
EJEMPLO 2 DE ESTRUCTURAS GENERICAS
class Persona {
public string Nombre { set; get; }
public int Edad { set; get; }
}
class EjemploColeccionGenerica {
static void Main(string[] args) {
Queue<Persona> personas = new Queue<Persona>();
personas.Enqueue(new Persona(){ Nombre = "Pedro", Edad = 32});
// al tratar de agregar un elemento 'extraño', produce un error
// personas.Enqueue(new int[]{1,2,3,4,5,6,7});
Persona pedro = personas.Dequeue();
Console.WriteLine("Nombre: "+pedro.Nombre+" Edad: "+pedro.Edad);
}
}
class EjemploColeccionNoGenerica {
static void Main(string[] args) {
Queue personas = new Queue();
personas.Enqueue(new Persona(){ Nombre = "Pedro", Edad = 32});
// al agregar un elemento 'extraño' lo almacena correctamente
personas.Enqueue(new int[]{1,2,3,4,5,6,7});
Persona pedro = (Persona)personas.Dequeue();
Console.WriteLine("Nombre: "+pedro.Nombre+" Edad: "+pedro.Edad);
}
}
Clases genéricas y LINQ
consultas LINQ basadas en tipos genericos
los DataSource deben implementar IEnumerable<T>
(permite enumerar y crear secuencias)
LINQ to Objects (Data Provider)
IEnumerable<Persona> personasMayores =
from per in personas
where per.Edad > 60
select per;
Query expression
var personasMayores =
from per in personas
where per.Edad > 60
select per;
method-base expression
Operadores de consultas en SQL
se aplican sobre DataSource seleccionados
-
filtrar
-
seleccionar
-
unir
-
ordenar
-
proyectar
Selección de la fuente de datos (from)
var seleccionados = from c in ciudades select c;
foreach (Ciudad c in seleccionados) Console.WriteLine("Nombre: "+c.NombreCiudad+" Comuna: "+c.Comuna);
from c in ciudades
Filtrado (where)
var ciudadesCurico = from c in ciudades where c.Comuna == "Curico"
where c-Ciudad != "Curico"
select c;
foreach (Ciudad ciud in ciudadesCurico) Console.WriteLine("Ciudad: " + ciud.NombreCiudad);
where [predicado]
debe ser TRUE
multiples where
Orden de los elementos (orderby)
var ciudOrdenDescendiente = from c in ciudades where c.Comuna == "Curico" orderby c.NombreCiudad descending select c;
foreach (Ciudad ciud in ciudOrdenDescendiente) Console.WriteLine("Ciudad: " + ciud.NombreCiudad);
igual a SQL
orderby [item] ascending
orderby [item] descending
orderby [item1, item2]
Proyección (projection, select)
var seleccion = from p in personas
select new { p.Nombre, p.Apellido };
foreach (var per in seleccion)
Console.WriteLine("Nombre: "+per.Nombre+"Apellido: "+per.Apellido);
proyectar una o más propiedades
uso de un objeto anonimo
Unión de diferentes secuencias (join)
var trabajadoresPorCiudad = from p in personas join c in ciudades on p.Ciudad equals c.NombreCiudad select new { p.Apellido, c.Comuna };
foreach (var trab in trabajadoresPorCiudad) Console.WriteLine("Apellido: "+trab.Apellido+" Comuna: "+trab.Comuna);
une dos series en las propiedades que tienen en comun
proyecta un objeto anonimo
igual a SQL
Unión de diferentes secuencias con elementos sin pareja (outer join)
var personasEnCiudades = from p in personas join c in ciudades on p.Ciudad equals c.NombreCiudad into grupoPersonas from comunaPersona in grupoPersonas.DefaultIfEmpty( new Ciudad { NombreCiudad = p.Ciudad, Comuna = "COMUNA POR DEFECTO" }
) select new { p.Apellido, comunaPersona.Comuna };
foreach (var pers in personasEnCiudades) Console.WriteLine("Apellido: "+pers.Apellido+" Comuna: "+pers.Comuna);
Outer Join
DefaultIfEmpty si un objeto no tiene equivalencia
Agrupación de datos (grouping)
var personasPorCiudad = from p in personas group p by p.Ciudad;
// recorrer los grupos generados foreach (var grupoPersonas in personasPorCiudad) { Console.WriteLine( String.Format("La ciudad {0} tiene {1} personas:", grupoPersonas.Key, grupoPersonas.Count() ));
// recorrer cada uno de las personas en los grupos foreach (var pers in grupoPersonas) Console.WriteLine(pers.Nombre+" "+pers.Apellido); }
posibilidad de aplicar SUM, MAX, MIN, AVERAGE, etc. sobre los grupos
Uso de DataContext
-
Crear la conexión con la base de datos
-
Envía y recibe objetos a una base de datos
-
Convierte objetos a SQL y viceversa
Ejemplo de datacontext
var listado = from o in context.objetos where o.cantidad> 1 select o;
var primero = listado.First(); Console.WriteLine("Elemento seleccionado ID: "+primero.id);
// eliminamos el elemento context.objetos.Remove(primero); context.SaveChanges();
// obtenemos nuevamente los datos desde la BD y mostramos foreach (objetos o in listado) Console.WriteLine("ID: "+o.id+" descripcion:"+o.descripcion);
Entidades de datos
ADO.NET Entity Framework
.NET Framework 3.5+
modelos conceptuales de tablas, vistas y p. almacenados
Entity Data Model Wizard crea las entidades de datos automaticamente
Entity framework y linq
provedor de datos LINQ to Entity
var db = new bg_ej03Entities();
var listado = from o in db.objetos where o.descripcion.StartsWith("N") select o;
foreach (objetos ob in listado) Console.WriteLine("Nombre: " + ob.descripcion);
RESUMEN
LINQ...
•... es un lenguaje de consulta de proposito general
• ... esta intregado en la plataforma .net
• ... esta integrado con Intellisense
• ... incluye operadores como filtros, join, proyectores, etc.
• ... puede ser optimizado por versiones nuevas del compilador
• ... puede ser invocado usando Sintaxis de consulta (Query Syntax)
• ... puede ser invocado usando Sintaxis con metodos (Method Syntax)
... se puede expandir al agregar DataProviders nuevos
LINQ
By Alejandro Silva
LINQ
- 1,343