LINQ

4

Click here to load reader

description

Describe algunos nuevos features de .net 3.0 y lo que será LINQ

Transcript of LINQ

Page 1: LINQ

Jair Cazarin [email protected]

http://jaircazarin.spaces.live.com

LINQ: Language Integrated Query

LINQ [1] es una extensión a los lenguages del .NET Framework, C# y Visual Basic .NET, planeada para ser lanzada con

Orcas [2] en este año.

El objetivo de LINQ es el de proveer a este par de lenguages de programación la posibilidad de hacer queries

nativamente desde el lenguaje, esto quiere decir ya no lidiar con SqlCommand, SqlDataReader, y demás objetos.

Para muestra, un ejemplo dónde se obtienen de un array de enteros los que son menores a 5:

public void Linq1() {

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

var lowNums =

from n in numbers

where n < 5

select n;

Console.WriteLine("Numbers < 5:");

foreach (var x in lowNums) {

Console.WriteLine(x);

}

}

Esto quiere decir, que LINQ no solo fue hecho para atacar el problema del miss-match entre las bases de datos

relacionales y los lenguajes de programación orientados a objetos, sino que funciona para cualquier clase que

implemente la intefaz IEnumerable [3] (Cualquier collection actualmente lo hace) e incluso también está hecho para

proporcionar todo el poder de Xquery [4] y Xpath [5] pero built-in en el lenguaje.

Para lograr todo esto LINQ utiliza las siguientes características del framework (Que también son nuevas):

● Anonymous Types.

● Extension Methods.

● Lambda Expressions.

● Expression Trees.

● Standard Query Operators.

Page 2: LINQ

Anonymous Types

Los anonymous types son un feature del .Net Framework 3.0 que permite crear tuplas ó tipos de datos inexistentes

automáticamente en tiempo de compilación. Pareciera complicado, pero es bastante sencillo. Lo que sucede es que si

necesitamos un objeto que contenga las propiedades “Nombre” y “Apellido”, por ejemplo para obtener los nombres y

apellidos de una lista de trabajadores guardada en una base de datos en SQL Server, normalmente lo que tendríamos

que hacer es crear nuestra class ó struct Trabajador, con estas 2 propiedades. Lo que nos permiten los Anonymous

Types, es solo asignar las propiedades que queramos a un object initializer con el keyword var y el compilador

automáticamente creará esta clase, con sus respectivas properties en tiempo de compilación.

Por ejemplo: var p1 = new {Name = "Jair", LastName = "Cazarin"};

Y nuestro compilador de C# 3.0 nos producirá algo así:

class __Anonymous1

{

private string name ;

private string lastName;

public string Name{ get { return name; } set { name = value ; } }

public string LastName{ get { return lastName; } set { lastName= value ; } }

}

__Anonymous1 p1 = new __Anonymous1();

p1.Name = "Jair";

p1.LastName = "Cazarin";

Extension Methods

Seguramente se preguntaron, cuando vieron el primer ejemplo, de dónde salieron los keywords select, y where si un

array no tiene estos métodos, y la respuesta es usando Extension Methods. Y el objetivo de los mismos es

precisamente ese, el de extender métodos y clases ya existentes. Ahora deben estar pensando, y no para eso era la

herencia? Así es, pero uno de los problemas es que cuando no se tiene acceso al código fuente, se vuelve muy

limitado ya que muchas clases restringen la herencia o a ciertas propiedades (Sealed Class [6]).

Para hacerlo solo necesitamos usar el keyword this en el argumento del método y que el método sea static. Ejemplo:

static class Program

{ static void Main(string[] args) { string s = "Hello, world"; s.Print(); }

static void Print(this string s) { Console.WriteLine(s); }}

En este caso estamos añadiendole la funcionalidad de Print a un string.

Lambda Expressions

Las lambda Expressions están basados en el Lambda Calculus [7] el cual viene desde mucho tiempo atrás en los

inicios de la computación y son una característica muy importante de los lenguajes funcionales como Lisp [8], fue

creado por Alonzo Church y Stephen Cole Kleene (Si, el de la cerradura de Kleene).

Lo que nos proporcionan las Lambda Expressions en C# son una forma más limpia de declarar lo que lanzó Microsoft

en .net 2.0: Anonymous Methods. Y para LINQ nos sirve para hacer expresiones muy poderosas y elegantes dentro del

statement where, solo como un ejemplo. Para tener una idea más clara de lo que son, supongamos como se haría un

delegate con Anonymous Methods:

Page 3: LINQ

delegate T Func<T>(T t);

Func<int> funcDel = delegate(int x) { return x + x; };

Y con lambda expressions sería así:

Func<int> lambda = x => x + x;

Mucho más sencillo, y para llamarlo solo necesitamos poner: lambda(1); por ejemplo.

Expression Trees

Esto es uno de los features más complicados, pero para los que han programado alguna vez en LISP no necesitan

ninguna explicación. Y se basa en el hecho de manejar expresiones (Lambda Expressions) como estructuras de datos

en lugar de código ejecutable y añade un gran poder a las Lambda Expressions. Como vimos, un Lambda expression

se puede declarar como código ejecutable y se puede usar simplemente como una función más. Sin embargo cuando

se usan mediante System.Query.Expression (Expression Tree) el delegate no es compilado en código ejecutable sino

como datos que son convertidos y compilados en el delegate original. Para usarla se deben compilar e invocar

explicitamente en la aplicación.

Func<int,int> f = x => x + 1;

Expression<Func<int,int>> expression = x => x + 1

Para usarla:

var originalDelegate = expression.Compile();

var three = originalDelegate.Invoke(2);

En el caso de LINQ sirve para poder llamar a funciones dentro de queries.

Standard Query Operators

Por último está el Standard que define las operaciones que se pueden hacer, mediante el uso de Extension Methods, y

que nos proporciona cosas como esta:

int[] nums = new int[] {1,2,3,4,5,6,7,8,9};

double avg = nums.Average();

Para obtener la lista completa del Standard, descargar el archivo Standar Query Operator Documentation [9] del sitio

de Microsoft.

Muchos personas piensan que los lenguajes de .net principalmente C# cada vez se está volviendo más tipo C++, pero

yo al contrario pienso que C# se está volviendo más perfecto cada vez que sacan una nueva versión. En este caso la

integración de query-syntax dentro del lenguaje se me hace extraordinario y que ningún lenguaje hasta ahorita ha

hecho.

Ya para finalizar algunos ejemplos más:

publicvoid Linq() {

List products = GetProductList();List customers = GetCustomerList();

var productFirstChars =

from p in products

select p.ProductName[0];

var customerFirstChars =

from c in customers

select c.CompanyName[0];

var commonFirstChars = productFirstChars.Intersect(customerFirstChars);

Page 4: LINQ

Console.WriteLine("Common first letters from Product names and Customer names:");

foreach (var ch in commonFirstChars) {

Console.WriteLine(ch);

}

}

publicvoid Linq() {

int[] factorsOf300 = { 2, 2, 3, 5, 5 };

var uniqueFactors = factorsOf300.Distinct();

Console.WriteLine("Prime factors of 300:");

foreach (var f in uniqueFactors) {

Console.WriteLine(f);

}

}

public void Linq() {

string[] words = { "cherry", "apple", "blueberry" };

var sortedWords =

from w in words

orderby w

select w;

Console.WriteLine("The sorted list of words:");

foreach (var w in sortedWords) {

Console.WriteLine(w);

}

}

Para descargarlo [10]. Y recomiendo mucho ver este video en Channel 9 del genio detrás de esto, Anders Hejlsberg

[11]

Referencias:

[1] http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx

[2] http:// msdn2.microsoft.com/en-us/vstudio/aa700830.aspx

[3] http:// msdn2.microsoft.com/en-us/vstudio/aa700830.aspx

[4] http:// aspnet.4guysfromrolla.com/articles/071603-1.aspx

[5] http://msdn2.microsoft.com/en-us/library/ms256453.aspx

[6] http://www.csharphelp.com/archives/archive158.html

[7] http://en.wikipedia.org/wiki/Lambda_calculus

[8] http://en.wikipedia.org/wiki/Lisp_programming_language

[9] Standard Query Operator Documentation

[10] Download

[11] http://channel9.msdn.com/showpost.aspx?postid=114680