Framework .NET 3.5 10 Linq
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
3,254
On Slideshare
3,254
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
70
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. LINQ
    Novedades en VB.NET 9.0 y C# 3.0
    Nuevas funcionalidades en el lenguaje
    Nuevos compiladores
    Nuevo IDE en Visual Studio y diseñadores gráficos
    Soporte para LINQ (Language Integrated Query)
    Manteniendo, eso sí, la compatibilidad hacia atrás, casi al 100%.
    Las funcionalidades añadidas asociadas a LINQ son:
    Sintaxis de consulta de datos.
    Variables implícitamente tipadas.
    Tipos anónimos.
    Inicializadores de objetos.
    Métodos de extensión.
    Expresiones Lambda.
    Las cuales pasaremos a ver a continuación para poder entender LINQ y su uso.
  • 2. LINQ
    Variables implícitamente tipadas:
    El tipo se deduce por parte del compilador y del Intellisense, en base al valor de inicialización.
    Fuertemente tipadas, no son generalizaciones del tipo “Variant”, pero serán del tipo más general “31/12/09” será un String.
    [C#]
    String nombre1 = “John”; // Declarada explícitamente como string
    Var nombre2 = “John”; // Implícitamente asumida como string
    Console.WriteLine(nombre2.GetType().Name); // Devuelve “String”
    Int edad1 = 34; // Explícitamenteinteger
    Var edad2 = 34; // Inferida como integer
    Console.Writeline(edad2.GetType().Name); // Devuelve “Int32”
    [VB]
    Dim nombre1 AsString = “John”‘Explícitamente string
    Dim nombre2 = “John”‘Implícitamente asumida como string
    Console.WriteLine(nombre2.GetType().Name) ‘ Devuelve “String”
    Dim edad1 AsInteger = 34 ‘ Explícitamente integer
    Dim edad2 = 34 ‘ Implícitamente asumida como integer
    Console.Writeline(edad2.GetType().Name ‘ Devuelve “Int32”
  • 3. LINQ
    Inicializadores de objetos.
    Nos permiten asignar valores a todos los campos y propiedades accesibles de un objeto en el momento de la creación sin tener que invocar explícitamente un constructor del mismo.
    List<Persona> gente = newList<Persona>(); [C#]
    Persona P = newPersona();
    P.Nombre = “Pepe”;
    P.Apellido = “Pérez”;
    P.Edad = 52;
    Gente.Add(P);
    // Nueva versión con inicializadores
    Gente.Add(newPersona{Nombre=“Pepe”,Apellido=“Pérez”,Edad=52});
    Dim gente AsNew List(Of Persona) [VB]
    Dim P As New persona
    P.Nombre = “Pepe”
    P.Apellido = “Pérez”
    P.Edad = 52
    Gente.Add(P)
    Gente.Add(New Persona With {.Nomre=“Pepe”,.Apellido=“Pérez”,.Edad=52})
  • 4. LINQ
    Tipos anónimos
    No es necesario declarar la clase.
    Se infiere el tipo de forma similar a las variables implícitamente tipadas.
    No dispondremos de nombre de clase, este será generado por el compilador heredando directamente de Object, por lo que no podremos referir a dicho nombre, motivo por el que son llamados anónimos.
    Están fuertemente tipados.
    No son apropiados si se ha de compartir la información con miembros o terceros, al no poder acceder al nombre de clase generado.
    [C#]
    var Empleado = new {Nombre=“JuanGómez”, Edad=33};
    [VB]
    Dim Empleado = NewWith {.Nombre=“JuanGómez”, .Edad=33}
  • 5. LINQ
    Tipos anónimos (II)
    Antes de decidirse a crear un objeto como una instancia de una clase anónima es necesario plantearse si esta es la mejor opción en ese caso.
    Si se desea crear objetos temporales y no hay necesidad de otros campos o métodos, un tipo anónimo puede ser una excelente solución.
    También pueden ser útiles si se necesita cambiar las propiedades en cada declaración o cambiar el orden de las mismas.
    Pero las limitaciones inherentes a los tipos anónimos hacen que no sean viables cuando debamos compartir información, al no aparecer la clase relacionada en ningún momento en el código y, por ende, ser imposible hacer referencia a la clase o pasarla como parámetro, al no poder declarar el tipo.
  • 6. LINQ
    public static class DemoExtensiones {
    public static int CuentaPalabras(thisString Frase) {
    return Frase.Split(new char[] {‘ ‘, ‘,’,’.’}).Length;
    }
    }
    classExtensiones {
    public void ExtensionesDetexto(){
    String FrasePrueba = “Esta es la prueba”;
    Console.WriteLine(FrasePrueba.CuentaPalabras());
    // Devuelve 4
    }
    }
    Métodos de extensión en C#
    Estos métodos son un complemento que nos permite la ilusión de estar añadiendo nuevos métodos de clase (static) a una clase existente, sin cambiar su definición, heredarla o tener que recompilar, accediendo a ellos como si fueran métodos de instancia.
    Se definen como métodos static, anteponiendo “this” a primer parámetro.
    Se llaman mediante una instancia específica.
    Se asocian al tipo de dato del primer parámetro (this).
  • 7. LINQ
    Imports System.Runtime.CompilerServices
    public Module UtilidadesGenerales
    <Extension()> Public Function CuentaPalabras(ByVal Frase As String) As Integer
    return Frase.Split(new char() {‘ ‘, ‘,’,’.’}).Length
    End Function
    End Module
    Public Class Extensiones
    public Sub ExtensionesDetexto()
    Dim FrasePrueba As String = “Esta es la prueba”
    MsgBox(FrasePrueba.CuentaPalabras)
    // Devuelve 4
    End Sub
    End Class
    Métodos de extensión en Visual Basic
    Estos métodos son un complemento que nos permite la ilusión de estar añadiendo nuevos procedimientos Sub o Function a una clase existente, sin cambiar su definición, heredarla o tener que recompilar.
    Hay que importar System.Runtime.CompilerServices
    Las extensiones se definen en Modules.
    Hay que añadir el atributo <Extension()> al procedimiento.
    Se asocia al tipo del primer parámetro.
  • 8. LINQ
    Uso de los métodos de extensión en LINQ
    Los métodos de extensión más comunes son los operadores estándar de LINQ, los cuales añaden funcionalidad a los tipos ya existentes en System.Collections.Ienumerable y System.Collections.Generic.Ienumerable(T).
    Para usar los operadores estándar de LINQ habremos de importar la directiva System.Linq.
    A partir de ese momento, cualquier tipo que implemente IEnumerable(Of T) parecerá disponer de métodos de instancia como GroupBy, OrderBy, Average, etc.
    Se pueden ver todos estos métodos desde IntelliSense, tras pulsar el punto en una de estas instancias (Ej: List(Of T) o Array.
  • 9. LINQ
    Expresiones Lambda.
    Las expresiones Lambda son funciones sin nombre que calculan y devuelven un valor único y pueden ser utilizados en el mismo lugar que los tipos delegados.
    Pueden contener tanto expresiones como sentencias.
    Son el mecanismo utilizado para implementar muchas de las funciones de consulta de LINQ(Where, Select, OrderBy, …)
    [C#]
    // Buscamos números pares en una lista ya construida
    NumerosPares = LosNumeros.FindAll(N => N % 2 == 0);
    // Frente a
    Public static bool EsPar(int N) {
    return N % 2 == 0;
    }
    NumerosPares = LosNumeros.FindAll(new Predicate<int>(EsPar));
    [VB]
    ‘Buscamos números pares en una lista ya construida
    NumerosPares = LosNumeros.FindAll(Function(N As Integer) N Mod 2 = 0)
    ‘ Frente a
    Public Shared Function EsPar(ByVal N As Integer) As Boolean
    Return N Mod 2 = 0
    End Function
    EvenNumbers = AllNumbers.FindAll(New Predicate(Of Integer) (AddressOfEsPar))
  • 10. LINQ
    Expresiones Lambda (II)
  • 11. LINQ
    ¿Qué es LINQ?
    Language Integrated Query
    Es un conjunto de operadores de consulta que pueden utilizarse para consultar, extraer o filtrar datos.
    Sólo puede acceder a datos suministrados por LinqProviders, los cuales encapsulan los datos fuente como objetos accesibles por las consultas Linq.
    Disponible en C# 3.0 y Visual Basic .NET 9.0.
    Otros lenguajes tendrán soporte para Linqmás adelante.
    Suministra librerías de clases para el conocimiento de los datos desde el código.
    Lo cual nos da las ventajas de la validación de sintaxis en tiempo de compilación y desde IntelliSense.
    Su principal objetivo es el de la consulta de los datos referenciados, aunque algunos LinqProviders permiten la actuación sobre dichos datos para su modificación.
  • 12. LINQ
    Antes del desarrollo de LINQ, los desarrolladores teníamos que conocer el lenguaje de consulta específico para cada tipo de origen de datos.
    Ahora LINQnos ofrece un modelo único de trabajo sobre datos, independientemente de su origen, sólo necesitaremos dominar un lenguaje de consulta de datos para acceder a colecciones de objetos, XML, DataSets, bases de datos, … etc.
    Aunque un conocimiento de la técnicas subyacentes siempre será beneficioso y permitirá optimizar nuestros procesos, como ocurre con todas las tecnologías de abstracción por capas.
    LINQpermite consultar un limitado conjunto de datos, aquellos suministrados por los Linq Data Providers:
    LINQ to Objects
    LINQ to Datastes.
    LINQ to XML.
    LINQ to Entities.
    LINQ to SQL.
    LINQ Data Providers de teerceros (Line Of Business Apps, Sharepoint, …) > 100.
  • 13. LINQ
    Query sintax
    Implicity Typed Variables
    Anonymous Types
    Object Initializers
    Extension Methods
    Lambda Expressions
  • 14. LINQ
    Requerimientos de LINQ
    Referencias en el proyecto:
    System.Core
    System.Xml.Linq
    System.Data.Linq
    System.Data-DataSetExtensions
    Espacios de nombres a importar:
    System.Linq
    System.Xml.Linq
    System.Data.Linq
    Compilación:
    Activar la opción de inferencia de tipos “Option Infer On”
  • 15. LINQ
    LINQ Data Providers
  • 16. LINQ
    Consultas LINQ
    Para ejecutar una consulta LINQ se deben seguir estos tres pasos:
    Configurar un origen de datos.
    Definir la consulta.
    Ejecutar la consulta.
    ‘Primer paso: Preparar datos de ejemplo
    Dim Gente As New List(Of Persona)
    Gente.Add(New Persona With{.Nombre=“Juan”, .Apellido=“Pérez”, .Edad=33})
    Gente.Add(New Persona With{.Nombre=“Pepe”, .Apellido=“Gómez”, .Edad=50})
    Gente.Add(New Persona With{.Nombre=“Leon”, .Apellido=“García”, .Edad=27})
    ‘Segundo paso: Definir la consulta
    Dim Consulta = Gente.Where(Function(P) P.Edad >= 30)
    ‘Tercer paso: Ejecutar la consulta
    For Each TreintaYTantos In Consulta
    Console.WriteLine({0} & “ “ & {1}, TreintaYTantos.Nombre, TreintaYTantos.Apellido)
    Next
    Este es un ejemplo muy sencillo, pero en el caso de otros orígenes de datos se requerirán:
    Dataset: necesitaremos un objeto DataSetadecuadamente rellenado con datos.
    Base de datos: deberemos configurar un DatContext, mediante LINQ to Entities o LINQ to SQL, que contenga una conexión a base de datos y los metadatos adecuados.
    Aquí simplemente se escribe una consulta utilizando los operadores de LINQ del lenguaje de nuestra elección.
    Habitualmente las consultas no se ejecutan en este paso, salvo que contengan funciones de agregado.
    Adicionalmente, esta consulta en particular hace uso de un método de extensión (Where) al que se le pasa una expresión Lambda.
  • 17. LINQ
    Opciones de sintaxis de LINQ
    Utilizar los métodos de extensión, aunque muy potentes y con un excelente rendimiento, no redunda en la legibilidad del código, más bien le añade un nivel más de densidad.
    Otra opción, que generará el mismo código intermedio por parte del compilador, para el ejemplo anterior, sería:
    Finalmente, aquí indicamos el aspecto que tendrá el resultado de ejecutar esta consulta. Podríamos haber recuperado el objeto completo de cada elemento de la lista que cumpla la condición. Como sólo recuperamos una propiedad de tipo String, pero puede haber más de un resultado en la consulta, el tipo devuelto será una colección de String.
    Utilizamos una variable de tipo implícito, cuyo tipo será inferido del resultado de la consulta. En este caso, una lista de nombres, por lo que el tipo será System.Collection.Generic.IEnumerable<String>
    Aquí indicamos nuestro origen de datos, en este caso la colección Gente, que en el ámbito de la consulta será conocida por P, y que será del tipo Persona, inferido del contenido de la lista.
    Aquí filtramos los elementos a recuperar mediante el valor de una de las propiedades del tipo contenido en el origen de datos.
    ‘ Segundo paso: Definir la consulta
    [C#]
    var TreintaYTantos = from P in Gente
    where P.Edad >= 30
    select P.Nombre;
    [VB]
    Dim TreintaYTantos = From P In Gente _
    Where P.Edad >= 30 _
    Select P.Nombre
  • 18. LINQ
    Operadores de consulta LINQ
    Las funciones son las mismas disponibles en SQL, aunque algún operador cambia de nombre (Take = Top)
  • 19. LINQ
    Proveedores de datos – LINQ To Objects
    Es una nueva forma de trabajar con las colecciones, muy superior al tradicional bucle For Each, ya que LINQnos ofrece herramientas para filtrar, ordenar y agrupar los elementos de la lista de objetos. Adicionalmente, es más fácil leer y comprender una instrucción LINQque seguir toda la lógica del código dentro de un bucle For Each, el cual puede ser muy largo.
    Ventajas con respecto a los bucles For Each :
    Conciso y legible.
    Con herramientas de filtrado, ordenación y agrupación.
    Migrable a otras fuentes de datos sin apenas cambios.
    Listas IEnumerable o IEnumerable<T> consultables:
    List<T> / List (Of Type)
    Array
    Dictionary(Tkey, Tvalue)
  • 20. LINQ
    Proveedores de datos – LINQ To Objects
    [VB] Version tradicional
    Private Class Clasificador
    Implements IComparer(Of Persona)
    Public Function Compare(ByVal x As Persona, ByVal y As Persona) _
    As Integer Implements System.Collections.Generic.IComparer _
    Of Persona).Compare
    If x.Ciudad <> y.Ciudad Then
    Return New CaseInsensitiveComparer().Compare(x.Ciudad, y.Ciudad)
    Else
    Return New CaseInsensitiveComparer().Compare(x.Edad, y.Edad)
    End If
    End Function
    End Class
    'Buscar a los mayores de 30, y ordenar por ciudad y edad
    Dim Temporal As New List(Of Persona)
    For Each P As Persona In Gente
    If P.Edad >= 30 Then Temporal.Add(P)
    Next
    Temporal.Sort(New Clasificador)
    Nueva version
    Dim TempResult = From P In Gente _
    Where P.Edad >= 30 _
    OrderBy P.Ciudad, P.Edad _
    Select P
    ' Pero puede tener un 25% menos rendimiento que el For Each
  • 21. LINQ
    Proveedores de datos – LINQ To Dataset
    Con el desarrollo separado por capas, es habitual que la capa de acceso a datos devuelva directamente un DataSetcon la composición de DataTablesy sus relaciones adecuadamente cumplimentada e informada.
    El acceso a esta información podía ser muy fácil o muy difícil, siempre en función de la composición del Datasety las relaciones entre las tablas que lo compongan.
    Ahora se ha simplificado un poco este tipo de búsquedas ya que disponemos de un proveedor de datos para LINQcontra Datasets(tipados o no tipados), el cual permite acceder a uno o más Datasetssimultáneamente, efectuar uniones entre DataTables o incluso entre DataTablesy otros tipos de datos.
    El acceso se efectúa al nivel DataTableen lugar de quedarse al nivel DataSet.
  • 22. LINQ
    Proveedores de datos – LINQ To Dataset (II)
    [C#]
    // Rellenamos un DataSet tipado
    Var DA = new dsProductsTableAdapters.ProductsTableAdapter();
    DA.Connection = DBConn;
    Var dtProductos = newdsProducts.ProductDataTable();
    DA.Fill(dtProductos);
    // Buscamos los 10 productos más caros
    Var MasCaros = (from P in dtProductos
    orderby P.ListPrice descending
    selectP.Take(10);
    // Mostramos el resultado
    Foreach (var P in MasCaros)
    Console.WriteLine(String.Format("{0} – cuesta:{1}", P.Nombre,P.Precio));
    [VB]
    ' Rellenamos un DataSet tipado
    Dim DA As New dsProductsTableAdapters.ProductsTableAdapter
    DA.Connection = DBConn
    Dim drProductos As New dsProducts.ProductDataTable
    DA.Fill(dtProductos)
    ' Buscamos los 10 productos más caros
    Dim MasCaros = From P In dtProductos _
    Order By P.Precio Descending _
    Take 10 _
    Select P
    ' Mostramos el resultado
    For Each P In masCaros
    Console.WriteLine(String.Format(("{0} – cuesta:{1}", P.Nombre,P.Precio))
    Next
    Especificamos la fuente de datos de la consulta, en este caso el DataTable antes definido sobre el DataSet, cuyo tipo devuelto será ProductRow, inferido del contenido del DataTable.
    Indicamos que deseamos sólo las 10 primeras filas de resultados.
    Declaramos una variable cuyo tipo será inferido del resultado de la consulta, en este caso será una colección enumerable del tipo ProductRow
    Utilizamos el operador OrderBy para especificar la ordenación deseada de los datos resultantes.
    Se especifica que la consulta debe devolver el objeto ProductRow completo para cada fila del conjunto de resultados.
  • 23. LINQ
    Acceso a datos con LINQ
    Esta herramienta tan potente nos permite acceder a datos almacenados mediante los siguientes orígenes de datos, adicionales a los ya revisados.
    LINQ to XML
    LINQ to Entities
    LINQ to SQL
  • 24. LINQ
    LINQ to XML
    No es ningún secreto que XMLes una metodología de implementación de archivos de texto de una forma estructurada que no puede ser dejada de lado por ningún desarrollador, ni ahora ni en un futuro próximo.
    Su implantación universal obliga a conocer y manipular adecuadamente este formato, por lo que .NET Framework 3.5 nos suministra nuevas herramientas para ello.
    Nueva API XML(XElement, XAttribute, XNamespace, etc)
    Proveedor de datos para LINQ.
    Los beneficios del uso de este estándar son:
    Es mejor y menos pesado que DOM.
    Es más fácil trabajar con este formato.
    Disponemos de validación en tiempo de compilación e InteliSense.
    Mejor soporte para depuración.
    Se puede cargar o serializar XMLdesde archivos o streams.
    Se puede crear y manipular árboles XMLen memoria.
    Es comparable a XPATH, XSLT(W3C) y XQueryen funcionalidad.
  • 25. LINQ
    LINQ to XML(II) – Creación de árboles XML
    Basándonos en los nuevos tipos de datos XMLpodemos crear fácilmente árboles XML:
    Desde código.
    Desde archivos de texto, TextReadero direcciones Web.
    Mediante un XmlReader(Xnode.ReadFrom)
    XML Generado:
    <?xml version="1.0" encoding="utf-8"?>
    <Email Prioridad="Alta">
    <Destinatario>pepito@ibis.es</Destinatario>
    <Asunto>Ejemplo XML – nueva version</Asunto>
    <Cuerpo>
    <Linea 1>Mas facil de usar</Linea 1>
    <Linea 2>Potente y productivo</Linea 2>
    </Cuerpo>
    </Email>
    [C#]
    XElement Example1 = newXElement("Email",
    newXAttribute("Prioridad", "Alta"),
    newXElement("Destintario", "pepito@ibis.es"),
    newXElement("Asunto", "Ejemplo XML – nueva version"),
    newXElement("Cuerpo",
    newXElement("Linea 1", "Mas facil de usar"),
    newXElement("Linea 2", "Potente y productivo")));
    [VB]
    Dim Example1 AsNew XElement("Email", _
    New XAttribute("Prioridad", "Alta"), _
    New XElement("Destinatario", "pepito@ibis.es "), _
    New XElement("Asunto", "Ejemplo XML – nueva version "), _
    New XElement("Cuerpo", _
    New XElement("Linea 1", "Mas facil de usar "), _
    New XElement("Linea 2", "Potente y productivo ")))
  • 26. LINQ
    LINQ to XML(III) – Literales XML en Visual Basic
    Permiten teclear (o pegar) texto XMLdirectamente en el código, ya que tiene el mismo aspecto que el XMLfinal.
    Tienen en cuenta los esquemas XMLaplicables.
    Permiten anidar código.
    Soportan los espacios de nombres XML.
    No requieren carácter de continuación de línea.
    Permiten el uso de IntelliSensesi hay un esquema aplicable.
    Dim Test = <EmailPrioridad="Alta">
    <Destinatario>pepito@ibis.es</Destinatario>
    <Asunto>¡Ahora <%= Now.ToShortDateString %>, VB.NET!</Asunto>
    <Cuerpo>
    <Linea 1>Literales XML - conciso, legible, claro</Linea 1>
    <Linea 2>Muy faciles de usar, muy potentes</Linea 2>
    </Cuerpo>
    </Email>
    Console.WriteLine(Test.@Prioridad & " prioridad del correo a & Test.<Destinatario>.Value)
    Expresiones embebidas
    Elemento
    Atributo
  • 27. LINQ
    LINQ to XML(IV) – Consultas
    Se pueden realizar consultas sobre tipos XDocumenty XElement.
    Es similar, pero más rápido y fácil que XPatho XQuery.
    Se puede obtener el mismo resultado que con XSLT, pero con menos código y esfuerzo.
    File: xmltest6.xml
    <?xml version="1.0" encoding="utf-8"?>
    <People>
    <Person Name="John ">
    <Age>33</Age>
    <City>London</City>
    </Person>
    <Person Name="Sally ">
    <Age>31</Age>
    <City>London</City>
    </Person>
    <Person Name="Alexander ">
    <Age>26</Age>
    <City>London</City>
    </Person>
    <Person Name="Sue ">
    <Age>32</Age>
    <City>London</City>
    </Person>
    </People>
    [C#]
    var XMLData = XDocument.Load("c:codexmltest6.xml");
    var ThirtyLondon = from P in XMLData.Descendants("Person")
    orderby P.Element("Age").Value
    where P.Element("City").Value == "London"
    selectnew {Name = P.Attribute("Name").Value,
    Age = P.Element("Age").Value,
    City = P.Element("City").Value};
    [VB
    Dim XMLData = XDocument.Load("c:codexmltest6.xml")
    Dim ThirtyLondon = From P In XMLData.<People>.<Person> _
    Where P.<Age>.Value > 30 And _
    P.<City>.Value = "London" _
    Order By P.<Age>.Value _
    SelectNew With {.Name = P.@Name, _
    .Age = P.<Age>.Value, _
    .City = P.<City>.Value}
  • 28. LINQ
    LINQ to Entities
    Esta funcionalidad de LINQestá íntimamente ligada a ADO.NETEntityFramework, por lo que empezaremos por hablar de esta nueva funcionalidad de acceso a datos de la versión 3.5.
    La mayoría de nuestras aplicaciones están construidas sobre una base de datos relacional, por lo que es evidente que, de alguna forma, habrán de interactuar con dicha base de datos.
    La estructura de tablas de las bases de datos no siempre es óptima para su acceso desde código y el modelo conceptual suele diferir mucho del modelo físico de los datos.
    El EntityData Modelde ADO.NET Entity Framework es la solución a este tipo de problemas ya que se construye un modelo "lógico" de los datos, definiendo el correspondiente interfaz con el modelo físico, permitiendo el acceso desde código mediante una construcción simplificada y adecuada de los datos, con un enfoque orientado a objetos, aunque los datos subyacentes no estén en este formato.
    Con lo que ADO.NET nos presenta las entidades de datos como objetos en el entorno, mediante el Object Services, lo cual los hace idóneos para ser atacados desde LINQ.
  • 29. LINQ
    LINQ to Entities (II)
    Al ser una primera versión, está claro que, como siempre, necesitará pulirse un poco para alcanzar su pleno potencial, pero ya es una herramienta muy potente y que facilita enormemente el trabajo de desarrollo en cuanto al acceso a datos y simplifica el desarrollo de las capas de acceso a datos.
    LINQto Entitieses el proveedor de datos de LINQespecializado en el acceso a este tipo de origen de datos orientados a objetos, sobre el que sólo se podrán efectuar consultas y recuperación de datos, pero no modificación, al menos en esta fase temprana de implantación de la herramienta, ya que mediante EntityFrameworksí que podemos acceder a los datos en modificación.
    Hay dos formas de consultar datos en el EntityFramework:
    LINQtoEntities
    EntitySQL, utilizando comandos ADO.NET
  • 30. LINQ
    LINQ to Entities (III) Entity Framework
    Uno de los objetivos de ADO.NET 3.5 es el de abstraer al desarrollador de la complejidad de los datos subyacentes y presentar un modelo conceptual de objetos (entidades).
    Para ello utiliza una arquitectura en 3 capas las cuales, una vez definidas las relaciones, se encargarán de gestionar automáticamente el enlace entre los objetos y los datos reales.
    ADO.NET
    Entity .
    Framework
    Modelo conceptual
    (EDM – Objetos de negocio)
    Mapping
    (Relaciona los modelos conceptual y lógico)
    Modelo lógico
    (El de la base de datos)
    Este modelo conceptual facilita la encapsulación de la complejidad de los datos hacia el programador y la posible evolución del esquema de la base de datos, sin afectar al código.
  • 31. LINQ
    LINQ to Entities (IV) Entity Framework
    En muchos casos el acceso a la base de datos puede resultar más complejo de que inicialmente parecía y el nivel de conocimiento de la estructura de los mismos condiciona el código y la funcionalidad que se puede desarrollar.
    Tipos anónimos
    Modelo Lógico
    SELECT p.FirstName, p.LastName, s.Email, s.Department
    FROM People p inner join Staff s on p.PersonID = s.PersonID
    WHERE p.City = 'Seattle'’
    SELECT p.FirstName, p.LastName, c.CourseName, c.Track
    FROM People p inner join Staff s on p.PersonID = s.PersonID
    inner join TrainerCourses tc on s.PersonID = tc.TrainerID
    inner join Courses c on tc.CourseID = c.CourseID
    WHERE P.City = 'Seattle'
    [C#]
    var Trainers = from T in TrainingContext.People.OfType<Trainer>()
    where T.City == "Seattle"
    selectnew
    { Firstname = T.FirstName,
    Lastname = T.LastName,
    Courses = from C in T.Courses
    selectnew {CourseName = C.CourseName,
    Track = C.Track}};
    [VB]
    Dim Trainers = From T In TrainingContext.People.OfType(Of Trainer)() _
    Where T.City = "Seattle" _
    SelectNewWith {.Firstname = T.FirstName, _
    .Lastname = T.LastName, _
    .Courses = From C In T.Courses _
    SelectNewWith {.CourseName = C.CourseName, _
    .Track = C.Track}}
    Mapping
    [C#]
    var Trainers = from T in TrainingContext.People.OfType<Trainer>()
    where T.City == "Seattle"
    selectnew {Firstname = T.FirstName,
    Lastname = T.LastName,
    Email = T.Email,
    Department = T.Department};
    [VB]
    Dim Trainers = From T In TrainingContext.People.OfType(Of Trainer)() _
    Where T.City = "Seattle" _
    SelectNewWith {.Firstname = T.FirstName, _
    .Lastname = T.LastName, _
    .Email = T.Email, _
    .Department = T.Department}
    Modelo Conceptual
  • 32. LINQ
    LINQ to Entities (V)
    La estructura del Entity Framework
    LINQ to Entities
    IEnumerable<T>
    Entity SQL Query
    EDM
    Object Services
    Modelo Conceptual
    Command Tree
    EntityDataReader
    Entity SQL Query
    Mapping
    EntityClient Data Provider
    DBDataReader
    Command Tree
    Modelo Lógico
    ADO.NET Data Providers
    Fuentes de datos
  • 33. LINQ
    LINQ to Entities (VI)
    Un vez definido nuestro modelo de entidades dispondremos de formas de consultar los datos:
    La tradicional, con sentencias de SQL/Transact-SQL.
    Utilizando consultas de Entity SQL contra el EDM.
    Atacar al EDM mediante LINQ toEntities.
    De hecho, construyen unas sobre otras, es decir, si atacamos mediante LINQ toEntities, habrá una traducción a Entity SQL por detrás, la cual, a su vez, se verá traducida a las correspondientes sentencias Transact-SQL para el acceso a los datos reales en la base de datos.
    Lo que desconoceremos, normalmente, es dónde se realizarán estas traducciones, ya que dependerá del soporte al modelo Entity Framework que suministre el servidor de la base de datos.
  • 34. LINQ
    LINQ to Entities (VII)
    Acceder al Entity Framework mediante LINQ toEntities
    Las consultas entrarán en el ámbito de un "ObjectContext".
    El cuál gestionará encapsulando el acceso a la capa de ObjectServices:
    La conexión(es) con la(s) base(s) de datos.
    Los metadatos de los modelos (Conceptual, mapping y lógico)
    La gestión del estado de los objetos (modificaciones, eliminaciones, nuevos…)
    Una instancia de ObjectContextse utiliza para:
    Acceder a los datos como objetos.
    Enlazar los resultados de las consultas (shape).
    Añadir, cambiar o eliminar objetos.
    Conservar los cambios en la fuente de datos.
    Hacer attach y detach de objetos en memoria.
    Serializar objetos, mediante el soporte a WCF.
    Gestionar las identidades de objetos y rastrear los cambios.
    Gestionar la concurrencia.
    Gestionar las conexiones.
    Gestionar las transacciones.
  • 35. LINQ
    LINQ to Entities (VIII)
    [C#]
    publicstaticvoid Demo1()
    {
    var TrainingContext = newTrainingEntities();
    var Trainers = from T in TrainingContext.People
    where T.City == "Seattle"
    select T;
    foreach (var T in Trainers)
    Console.WriteLine(String.Format("Name: {0} {1}", T.FirstName,
    T.LastName ));
    }
    [VB]
    PublicShared Sub Demo1()
    Dim TrainingContext = New TrainingEntities
    Dim Trainers = From T In TrainingContext.People _
    Where T.City = "Seattle" _
    Select T
    ForEach T In Trainers
    Console.WriteLine(String.Format("Name: {0} {1}",T.FirstName, _
    T.LastName))
    Next
    EndSub
  • 36. LINQ
    LINQ to Entities (IX)
    La obtención de los resultados de la consulta se difiere hasta que dichos resultados sean necesarios.
    Los objetos relacionados no se cargan automáticamente, como en LINQto SQL, sino que hemos de especificarlo explícitamente mediante el método Loadde las propiedades de navegación, el cual nos devolverá una EntityCollectiono EntityReference.
    Salvo que sepamos de antemano que un objeto relacionado será necesario, en cuyo caso puede ser "incluido" en la consulta.
    publicstaticvoid Demo9() {
    var TrainingContext = newTrainingEntities();
    var Trainers = from T in TrainingContext.People.OfType<Trainer>()
    where T.City == "Seattle"
    select T;
    foreach (var T in Trainers) {
    Console.WriteLine(String.Format("Name: {0} {1}", T.FirstName, T.LastName));
    // Now explicitly load this Trainer's courses.
    T.Courses.Load();
    foreach (var C in T.Courses)
    Console.WriteLine(" Course: " + C.CourseName);
    }
    }
    Dim TrainingContext = New TrainingEntities()
    Dim Trainers = From T In TrainingContext.People.OfType(Of Trainer)().Include("Courses") _
    Where T.City = "Seattle" _
    Select T
    ForEach T In Trainers
    Console.WriteLine([String].Format("Name: {0} {1}", T.FirstName, T.LastName))
    ForEach C In T.Courses
    Console.WriteLine(" Course: " & C.CourseName)
    Next
    Next
  • 37. LINQ
    LINQ to Entities (X) – Traducción de las consultas
    SELECT [Project3].[CourseName] AS [CourseName]
    FROM
    ( SELECT [Extent1].[CourseName] AS [CourseName],
    ( SELECT COUNT(cast(1 as bit)) AS [A1]
    FROM [dbo].[People] AS [Extent2]
    LEFT OUTER JOIN
    ( SELECT [Extent3].[PersonID] AS [PersonID], cast(1 as bit) AS [C1]
    FROM [dbo].[Staff] AS [Extent3]
    ) AS [Project1]
    ON [Extent2].[PersonID] = [Project1].[PersonID]
    WHERE
    ( CASE WHEN
    ( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)))
    THEN '2X'
    ELSE '2X0X'
    END LIKE '2X0X%'
    )
    AND
    (N'Seattle' = [Extent2].[City])
    AND
    ( EXISTS
    ( SELECT cast(1 as bit) AS [C1]
    FROM
    ( SELECT [TrainerCourses].[CourseID] AS [CourseID],
    [TrainerCourses].[TrainerID] AS [TrainerID]
    FROM [dbo].[TrainerCourses] AS [TrainerCourses]
    ) AS [Extent4]
    WHERE ([Extent2].[PersonID] = [Extent4].[TrainerID])
    AND ([Extent4].[CourseID] = [Extent1].[CourseID])
    )
    )
    ) AS [C1]
    FROM [dbo].[Courses] AS [Extent1]
    ) AS [Project3]
    WHERE [Project3].[C1] > 1
    Dim CoursesInSeattle = From C In TrainingCtx.Courses _
    Where (From T In TrainingCtx.People.OfType(Of Trainer)() _
    Where T.City = "Seattle" _
    And T.Courses.Any(Function(F) F.CourseID = C.CourseID) _
    Select T).Count > 1 _
    Select C.CourseName
    eCom.CommandText = "SELECT C " & _
    "FROM TrainingEntities.Courses as C " & _
    "WHERE COUNT(select VALUE Trainer.PersonID " & _
    "from C.Trainer " & _
    "where Trainer.City = Seattle') > 1"
  • 38. LINQ
    Entity Framework, añadir datos
    Para añadir datos mediante el Entity Framework deberemos:
    Crear un nuevo objeto del tipo adecuado.
    Informar todas sus propiedades, al menos las obligatorias.
    Ejecutar el método AddToXXX correspondiente.
    Salvar los cambios en el origen de datos.
    [C#]
    //Crear un ObjectContext.
    var TrainingCtx = new TrainingEntities();
    // Paso 1: Crer un objeto Trainer e informar sus propiedades
    var NewTrainer = Trainer.CreateTrainer(22, "Carol", "Smith",
    "Training", "csmith@contoso.com", "cs705", "Mrs");
    // Paso 2: Informar también las no obligatorias
    NewTrainer.City = "London";
    NewTrainer.Phone = "555-54321";
    // Paso 3: Añadir el Trainer a las collecciones
    TrainingCtx.AddToPeople(NewTrainer);
    // Paso 4: Salvar los cambios
    TrainingCtx.SaveChanges();
    [VB]
    'Crear un ObjectContext.
    Dim TrainingCtx = New TrainingEntities
    'Paso 1: Crer un objeto Trainer e informar sus propiedades
    Dim NewTrainer = Trainer.CreateTrainer(16, "Peter", "Willford", _
    "Training", "pwillford@contoso.com","pw706", "Mr")
    ' Paso 2: Informar también las no obligatorias
    NewTrainer.City = "London"
    NewTrainer.Phone = "555-889767"
    ' Paso 3: Añadir el Trainer a las collecciones
    TrainingCtx.AddToPeople(NewTrainer)
    ' Paso 4: Salvar los cambios
    TrainingCtx.SaveChanges()
  • 39. LINQ
    LINQ to SQL
    Aunque la metodología preferida será en un futuro próximo LINQ toEntities, ya que Microsoft ha comunicado que no habrá actualizaciones ni mejoras al LINQ to SQL, esta es, de momento, la metodología actual en muchas instalaciones, debido a su sencillez (relativa) y a que Entity Framework no estaba aún disponible o se considera una tecnología no lo suficientemente madura y sujeta a posibles cambios.
    Algunas de las características de esta tecnología son:
    LINQ to SQL es una implementación de acceso mediante objetos a datos almacenados de forma relacional, utilizando para ello un modelo de objetos de datos.
    Permite un mapeo directo contra el esquema subyacente de SQL Server.
    Soporta tablas, transacciones, vistas y procedimientos almacenados.
    Permite la selección, inserción, actualización y eliminación de datos.
    Lógicamente estas funcionalidades se realizan mediante la traducción simultánea en ambos sentidos.
  • 40. LINQ
    LINQ to SQL(II) – Sintaxis de consulta
    [C#]
    var TrainingCtx = new LINQtoSQL.LINQtoSQLTrainingDataContext();
    var People = from P in TrainingCtx.Peoples
    orderby P.LastName
    select P;
    foreach (var P in People) {
    if (P.Staff != null) {
    Console.WriteLine("Trainer: {0} {1} Email:{2}", P.FirstName,
    P.LastName, P.Staff.Email);
    }
    else
    Console.WriteLine("Person: {0} {1}", P.FirstName, P.LastName);
    }
    [VB]
    Dim TrainingCtx = New LINQtoSQL.LINQtoSQLTrainingDataContext
    Dim People = From P In TrainingCtx.Peoples _
    Order By P.LastName _
    Select P
    For Each P In People
    If P.Staff IsNot Nothing Then
    Console.WriteLine("Trainer: {0} {1} Email:{2}", _
    P.FirstName, P.LastName, P.Staff.Email)
    Else
    Console.WriteLine("Person: {0} {1}", P.FirstName, P.LastName)
    End If
    Next
  • 41. LINQ
    LINQ to SQL(III)
    Como en el caso de LINQ toEntities, la ejecución de las consultas se difiere hasta que los resultados sean necesarios.
    Aunque la carga de datos relacionados está habilitada por defecto (LazyLoading).
    Para desactivarla deberemos modificar las DataLoadOptionsdel objeto ObjectContext.
    [c#]
    var TrainingCtx = new LINQtoSQL.LINQtoSQLTrainingDataContext();
    //Desactivar Lazy Loading
    TrainingCtx.DeferredLoadingEnabled = false;
    [VB]
    Dim TrainingCtx = New LINQtoSQL.LINQtoSQLTrain
    'Desactivar Lazy Loading
    TrainingCtx.DeferredLoadingEnabled = False
  • 42. LINQ
    LINQ to SQL(III) – Añadir datos
    [C#]
    var TrainingCtx = new LINQtoSQL.LINQtoSQLTrainingDataContext();
    var NewPerson = new LINQtoSQL.People();
    NewPerson.PersonID = 32;
    NewPerson.FirstName = "John";
    NewPerson.LastName = "Sawyer";
    NewPerson.City = "London";
    NewPerson.Phone = "555-32432";
    TrainingCtx.Peoples.InsertOnSubmit(NewPerson);
    TrainingCtx.SubmitChanges();
    [VB]
    Dim TrainingCtx = New LINQtoSQL.LINQtoSQLTrainingDataContext
    Dim NewPerson = New LINQtoSQL.People
    NewPerson.PersonID = 31
    NewPerson.FirstName = "John"
    NewPerson.LastName = "Sawyer"
    NewPerson.City = "London"
    NewPerson.Phone = "555-32432"
    TrainingCtx.Peoples.InsertOnSubmit(NewPerson)
    TrainingCtx.SubmitChanges()
    1º - Crear un nuevo objeto del tipo adecuado
    2º - Cumplimentar sus propiedades
    3º - pasar el objeto al método adecuado.
    4º - Salvar los cambios para que se efectúe la inserción
  • 43. LINQ
    LINQ to SQL(III) – Modificar datos
    [C#]
    var TrainingCtx = new LINQtoSQL.LINQtoSQLTrainingDataContext();
    var ThePerson = TrainingCtx.Peoples.Single(P => P.PersonID == 3);
    ThePerson.Phone = "555-33345";
    TrainingCtx.SubmitChanges();
    [VB]
    Dim TrainingCtx = New LINQtoSQL.LINQtoSQLTrainingDataContext
    Dim ThePerson = _
    TrainingCtx.Peoples.Single(Function(P) P.PersonID = 3)
    ThePerson.Phone = "555-33345"
    TrainingCtx.SubmitChanges()