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,332