La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

LINQ (Language-Integrated Query) Gabriel Espinoza Erices 2012 – 03 – 15.

Presentaciones similares


Presentación del tema: "LINQ (Language-Integrated Query) Gabriel Espinoza Erices 2012 – 03 – 15."— Transcripción de la presentación:

1 LINQ (Language-Integrated Query) Gabriel Espinoza Erices 2012 – 03 – 15

2 INTRODUCCIÓN LINQ es una innovación para disminuir la brecha entre el mundo de los objetos y el mundo de los datos.

3 INTRODUCCIÓN En Visual Studio, se pueden escribir consultas LINQ en VB o C# con: – Bases de datos SQL Server (Linq to SQL) – Documentos XML (Linq to XML) – DataSets ADO.NET (Linq to DataSet) – Colecciones de objetos que soporten IEnumerable o IEnumerable Requiere.NET Framework 3.5+

4 QUERYABLE TYPES Los tipos que soportan IEnumerable o derivan de interfaces como IQueryable son llamados Queryable Types Un objeto “queryable type” no requiere modificación ni trato especial para servir como datasource de LINQ. Si los datos orígenes no están en memoria como “queryable type”, el proveedor de LINQ debe representarlo como si estuviera.

5 LINQ TO SQL COMO QUERYABLE TYPE Con LINQ to SQL, primero se crea un mapeo objeto-relacional en tiempo de diseño, se crean las querys contra esos objetos. Luego en tiempo de ejecución, LINQ to SQL maneja la comunicación con la base de datos.

6 LA QUERY La query especifica qué información obtener de una o varias fuentes. Opcionalmente la query también puede especificar como esos datos deben ser ordenados, agrupados y formados antes de ser retornada. Una query tiene 3 clausulas: – from: Especifica el data source – where: aplica el filtro – select: especifica el tipo de los elementos retornados.

7 EJECUCIÓN DE LA QUERY La query por si misma no ejecuta ninguna acción ni retorna datos. Solo almacena la información requerida para producir los resultados cuando la consulta sea ejecutada en un punto posterior.

8 FORZAR EJECUCIÓN INMEDIATA Las querys que realizan funciones de agregado sobre un rango de fuentes, primero deben iterar sobre esos elementos. Ej: Count, Max, Average, First, etc. Notar que estas consultas no retornan una colección, sino que un valor. Para forzar la ejecución inmediata de cualquier query y almacenar en cache sus resultados, se pueden usar el ToList o ToArray

9 Son equivalentes SINTAXIS

10 OPERACIONES BÁSICAS Delcaración del DataSource Range Variable DataSource Declaración de filtros Da “forma” al resultado de la query

11 ORDER BY & JOINS Ordenamiento Un join crea asociaciones entre secuencias que no estén explicitamente modeladas en los DataSources. En LINQ los join SIEMPRE funcionan contra objetos y no tablas de bases de datos

12 AGRUPAR Agrupar: Al agrupar, se forma una lista de listas. La cláusula group permite agrupar los resultados basados en una llave que se especifique. Ejemplo: Los resultados agrupados por ciudad, de tal manera que los clientes de Londres o Paris son grupos individuales. En este caso cust.City es la llave. Si se necesita interactuar con el grupo, se puede usar into para crear una variable que lo referencie

13 CONSULTAS y TRANSFORMACIONES DE TIPOS DE DATO

14 LINQ y CLASES GENÉRICAS IEnumerable es la interfaz que habilita que las colecciones de clases genéricas puedan ser enumeradas usando la sentencia foreach. Las colecciones de clases genéricas soportan IEnumerable tal como las colecciones no genéricas (arraylists). Cuando veas que una query está escripta como IEnumerable, significa que la query, cuando sea ejecutada, producirá una secuencia de 0 o más objetos Customer.

15 LINQ y CLASES GENÉRICAS Se puede dejar que el compilador maneje la declaración genérica.

16 POR QUÉ LINQ VENCE A SQL Supongamos queremos hacer una consulta simple SELECT UPPER(Name) FROM Customer WHERE Name LIKE 'A%' ORDER BY Name SELECT UPPER(Name) FROM Customer WHERE Name LIKE 'A%' ORDER BY Name Ahora supongamos que estos resultados están alimentando una página web y queremos obtener solo las filas 21-30. De la nada, ahora necesitamos una subquery SELECT UPPER(Name) FROM ( SELECT *, RN = row_number() OVER (ORDER BY Name) FROM Customer WHERE Name LIKE 'A%' ) A WHERE RN BETWEEN 21 AND 30 ORDER BY Name SELECT UPPER(Name) FROM ( SELECT *, RN = row_number() OVER (ORDER BY Name) FROM Customer WHERE Name LIKE 'A%' ) A WHERE RN BETWEEN 21 AND 30 ORDER BY Name

17 POR QUÉ LINQ VENCE A SQL Y si necesitamos agregar soporte para bases de datos anteriores a SQL SERVER 2005, se vuelve peor aún!! SELECT TOP 10 UPPER (c1.Name) FROM Customer c1 WHERE c1.Name LIKE 'A%' AND c1.ID NOT IN ( SELECT TOP 20 c2.ID FROM Customer c2 WHERE c2.Name LIKE 'A%' ORDER BY c2.Name ) ORDER BY c1.Name SELECT TOP 10 UPPER (c1.Name) FROM Customer c1 WHERE c1.Name LIKE 'A%' AND c1.ID NOT IN ( SELECT TOP 20 c2.ID FROM Customer c2 WHERE c2.Name LIKE 'A%' ORDER BY c2.Name ) ORDER BY c1.Name No solo es complicado, sino que viola el principio DRY (Don’t Repeat Yourself)

18 IQueryable Paginate (this IQueryable query, int skip, int take) { return query.Skip(skip).Take(take); } var thirdPage = query.Paginate (20, 10); IQueryable Paginate (this IQueryable query, int skip, int take) { return query.Skip(skip).Take(take); } var thirdPage = query.Paginate (20, 10); POR QUÉ LINQ VENCE A SQL SELECT TOP 10 UPPER (c1.Name) FROM Customer c1 WHERE c1.Name LIKE 'A%' AND c1.ID NOT IN ( SELECT TOP 20 c2.ID FROM Customer c2 WHERE c2.Name LIKE 'A%' ORDER BY c2.Name ) ORDER BY c1.Name SELECT TOP 10 UPPER (c1.Name) FROM Customer c1 WHERE c1.Name LIKE 'A%' AND c1.ID NOT IN ( SELECT TOP 20 c2.ID FROM Customer c2 WHERE c2.Name LIKE 'A%' ORDER BY c2.Name ) ORDER BY c1.Name Aquí tenemos la misma consulta pero en LINQ. La ganancia en simplicidad es clara. var query = from c in db.Customers where c.Name.StartsWith("A") orderby c.Name select c.Name.ToUpper(); var thirdPage = query.Skip(20).Take(10); var query = from c in db.Customers where c.Name.StartsWith("A") orderby c.Name select c.Name.ToUpper(); var thirdPage = query.Skip(20).Take(10); Composability: Podemos dividir la consulta y hacer métodos genéricos reutilizables

19 SELECT p.* FROM Purchase p LEFT OUTER JOIN Customer c INNER JOIN Address a ON c.AddressID = a.ID ON p.CustomerID = c.ID WHERE (a.State = 'WA' || p.CustomerID IS NULL) AND p.ID in ( SELECT PurchaseID FROM PurchaseItem GROUP BY PurchaseID HAVING SUM (SaleAmount) > 1000 ) SELECT p.* FROM Purchase p LEFT OUTER JOIN Customer c INNER JOIN Address a ON c.AddressID = a.ID ON p.CustomerID = c.ID WHERE (a.State = 'WA' || p.CustomerID IS NULL) AND p.ID in ( SELECT PurchaseID FROM PurchaseItem GROUP BY PurchaseID HAVING SUM (SaleAmount) > 1000 ) Otro beneficio de LINQ es que puedes consultar a través de relaciones sin tener que hacer joins. var purchases = from p in db.Purchases where p.Customer.Address.State == "WA“ || p.Customer == null where p.PurchaseItems.Sum(pi => pi.SaleAmount) > 1000 select p; var purchases = from p in db.Purchases where p.Customer.Address.State == "WA“ || p.Customer == null where p.PurchaseItems.Sum(pi => pi.SaleAmount) > 1000 select p;

20 Parametrización: No hay que complicarse con los ataques de inyección de SQL pues la parametrización de LINQ es inline, segura y altamente legible. IQueryable GetCustomers (string state, decimal? minPurchase) { var query = Customers.AsQueryable(); if (state != null) query = query.Where (c => c.Address.State == "WA"); if (minPurchase != null) query = query.Where (c => c.Purchases.Any (p => p.Price > minPurchase.Value)); return query; } IQueryable GetCustomers (string state, decimal? minPurchase) { var query = Customers.AsQueryable(); if (state != null) query = query.Where (c => c.Address.State == "WA"); if (minPurchase != null) query = query.Where (c => c.Purchases.Any (p => p.Price > minPurchase.Value)); return query; } SELECT [t0].[ID], [t0].[Name], [t0].[AddressID] FROM [Customer] AS [t0] SELECT [t0].[ID], [t0].[Name], [t0].[AddressID] FROM [Customer] AS [t0] Si pasamos state y minPurchase nulos SELECT [t0].[ID], [t0].[Name], [t0].[AddressID] FROM [Customer] AS [t0] LEFT OUTER JOIN [Address] AS [t1] ON [t1].[ID] = [t0].[AddressID] WHERE (EXISTS( SELECT NULL AS [EMPTY] FROM [Purchase] AS [t2] WHERE ([t2].[Price] > @p0) AND ([t2].[CustomerID] = [t0].[ID]) )) AND ([t1].[State] = @p1) SELECT [t0].[ID], [t0].[Name], [t0].[AddressID] FROM [Customer] AS [t0] LEFT OUTER JOIN [Address] AS [t1] ON [t1].[ID] = [t0].[AddressID] WHERE (EXISTS( SELECT NULL AS [EMPTY] FROM [Purchase] AS [t2] WHERE ([t2].[Price] > @p0) AND ([t2].[CustomerID] = [t0].[ID]) )) AND ([t1].[State] = @p1) Si pasamos ambos valores LINQ no solo agregará los predicados, sino que también los JOINS

21 Cuándo no usar LINQ A pesar de su poder, LINQ no deja obsoleto a SQL. Toma más del 95% de la funcionalidad de las queries, pero se seguirá necesitando SQL para: Queries que busquen máxima optimización. Queries que involucren seleccionar en tablas temporales y luego consultar esas tablas. Actualizaciones con predicados e inserciones masivas (bulk) Triggers

22 Tener que conocer dos lenguajes para querys no es realmente un problema, dado que de todas maneras LINQ provee una forma común para interactuar con distintas fuentes de datos. Arreglos, Listas, XML, Bases de Datos, y en general, de cualquier objeto que herede de IQueryable y IEnumerable.

23 Fuentes http://msdn.microsoft.com/en- us/library/bb397933.aspx http://msdn.microsoft.com/en- us/library/bb397933.aspx http://msdn.microsoft.com/en- us/library/bb397926.aspx http://msdn.microsoft.com/en- us/library/bb397926.aspx http://www.codeproject.com/Articles/230380 /LINQ-to-SQL-Advanced-Concepts-and- Features http://www.codeproject.com/Articles/230380 /LINQ-to-SQL-Advanced-Concepts-and- Features http://www.linqpad.net/WhyLINQBeatsSQL.as px http://www.linqpad.net/WhyLINQBeatsSQL.as px


Descargar ppt "LINQ (Language-Integrated Query) Gabriel Espinoza Erices 2012 – 03 – 15."

Presentaciones similares


Anuncios Google