lenguaje integrado de consultas linq

52
Lenguaje Integrado de consultas LINQ Eduardo Quintás

Upload: tangia

Post on 23-Feb-2016

121 views

Category:

Documents


1 download

DESCRIPTION

Lenguaje Integrado de consultas LINQ. Eduardo Quintás. Guía. Novedades en C# 3.0 Fundamentos de LINQ Linq To Objects Linq To XML Linq To Entities Recursos. Novedades en C#3.0. Lenguaje Integrado de Consultas: LINQ. Evolución de .NET. C# 3.0 - Objetivos. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Lenguaje Integrado de consultas LINQ

Lenguaje Integrado de consultasLINQEduardo Quintás

Page 2: Lenguaje Integrado de consultas LINQ

Guía•Novedades en C# 3.0•Fundamentos de LINQ•Linq To Objects•Linq To XML•Linq To Entities•Recursos

Page 3: Lenguaje Integrado de consultas LINQ

Novedades en C#3.0Lenguaje Integrado de Consultas: LINQ

Page 4: Lenguaje Integrado de consultas LINQ

Evolución de .NET2002 2003 2005 2006 2007 2010

Herramienta(Visual Studio)

VS 2002 VS 2003 VS2005VS2005

+ Extensiones

VS2008 VS2010

LenguajeC# v1.0VB.NET (v7.0)

C# v1.1VB.NET (v7.1)

C# v2.0VB2005 (v8.0)

como antes

C# v3.0VB9

(v9.0)

C# 4.0VB10

(v10.0)

Librerías Framework

NetFx v1.0

NetFx v1.1

NetFx v2.0

NetFx v3.0

NetFx v3.5

NetFxV4.0

Engine (CLR) CLR v1.0 CLR v1.1 CLR v2.0 como

antescomo antes

CLR v4.0

Page 5: Lenguaje Integrado de consultas LINQ

C# 3.0 - ObjetivosIntegrar objetos, datos relacionales y XML

Y:Hacer el lenguaje más conciso

Añadir constructores de programación funcional

No ligar el lenguaje a APIs específicas

Mantenerse 100% compatible hacia atrás

Page 6: Lenguaje Integrado de consultas LINQ

Resultado: •Métodos extensores, tipos anónimos,

constructores sin parámetros, inferencia de tipos, expresiones lambda, árboles de expresión

•Más un poquito de azucar sintáctico …

from p in Passengerswhere p.Citizenship == “ES”select new { p.Id, p.Name };

Page 7: Lenguaje Integrado de consultas LINQ

Nuevas características•Inicializadores de objetos•Inferencia de tipos•Tipos anónimos•Métodos extensores•Expresiones lambda•Árboles de expresión•LINQ!!!

Page 8: Lenguaje Integrado de consultas LINQ

Inicializadores de Objetospublic class Passenger{ public string Id {get; set;} public string Name {get; set;} public DateTime BirthDate {get; set;}}

Passenger p = new Passenger () { Id = “A4”, Name = “Cabezabolo, Manolo” };

Passenger p = new Passenger();p.Id = “A4”;p.Name = “Cabezabolo, Manolo”;

Asignación de Campos o

Propiedadespublic Passenger(string id, string name, DateTime birthDate) // OPCIONAL!!!!{ Id=id; Name=name; BirthDate = birthDate; }

Page 9: Lenguaje Integrado de consultas LINQ

Inferencia de Tiposint i = 666;string s = “Hola";double d = 3.14;int[] numbers = new int[] {1, 2, 3};Dictionary<int,Pedido> pedidos = new Dictionary<int,Pedido>();

var i = 666;var s = “Hola";var d = 3.14;var numbers = new int[] {1, 2, 3};var pedidos = new Dictionary<int,Pedido>();

“El tipo en el lado de la derecha”

Page 10: Lenguaje Integrado de consultas LINQ

Tipos Anónimos

var o = new { Name = “Pantoja”, Age= 75 };

class XXX{ public string Name; public int Age;}

XXX

Page 11: Lenguaje Integrado de consultas LINQ

Métodos Extensoresnamespace MisCosas{ public static class Extensiones { public static string Concatenar(this IEnumerable<string> strings, string separador) {…} }}

using MisCosas;

string[] nombres = new string[] { “Edu", “Juan", “Manolo" };string s = nombres.Concatenar(", ");

Método extensor

Incluir extensiones en el ámbito

obj.Foo(x, y)

XXX.Foo(obj, x, y)

IntelliSense!

Page 12: Lenguaje Integrado de consultas LINQ

Expresiones Lambdapublic delegate bool Predicate<T>(T obj);

public class List<T>{ public List<T> FindAll(Predicate<T> test) { List<T> result = new List<T>(); foreach (T item in this) if (test(item)) result.Add(item); return result; } …}

Delegado genérico

Tipogenérico

Page 13: Lenguaje Integrado de consultas LINQ

Expresiones Lambdapublic class MiClase{ public static void Main() { List<Cliente> clientes = ObtenerListaClientes(); List<Cliente> locales = clientes.FindAll( new Predicate<Cliente>(CiudadIgualCoruna) ); }

static bool CiudadIgualCoruna(Cliente c) { return c.Ciudad == “A Coruña"; }}

Page 14: Lenguaje Integrado de consultas LINQ

Expresiones Lambda

public class MiClase{ public static void Main() { List<Cliente> clientes = ObtenerListaClientes (); List<Cliente> locales = clientes.FindAll( delegate(Cliente c) { return c.Ciudad == “A Coruña"; } ); }}

DelegadoAnónimo

Page 15: Lenguaje Integrado de consultas LINQ

Expresiones Lambdapublic class MiClase{ public static void Main() { List<Cliente> clientes = ObtenerListaClientes (); List<Cliente> locales = clientes.FindAll( (Clientes c) => {return c.Ciudad == “A Coruña";} ); }}

ExpresiónLambda

Page 16: Lenguaje Integrado de consultas LINQ

Expresiones Lambdapublic class MiClase{ public static void Main() { List<Cliente> clientes = ObtenerListaClientes (); List<Cliente> locales = clientes.FindAll(c => c.Ciudad == “A Coruña"); }}

ExpresiónLambda

Page 17: Lenguaje Integrado de consultas LINQ

Introduciendo LINQ•Todos estos nuevos aspectos se trasladan

a métodos extensores sobre colecciones:▫Pueden transformarse en árboles de

expresionesfrom p in passengerswhere p.Citizenship== “ES"select new { p.Id, p.Name };

passengers.Where(p => c.Citizenship == “ES").Select(p => new { p.Id, p.Name });

Page 18: Lenguaje Integrado de consultas LINQ

var pasajerosNacionales = from p in passengers where p.Citizenship == “ES" select new {p.Id, p.Name};

var pasajerosNacionales = passengers .Where(p => p.Citizenship== “ES") .Select(p => new { p.Id, p.Name});

Métodos Extensore

s

Expresiones

Lambda

Expresiones de Consulta

Inicializadores de Objetos

Tipos Anónimos

Inferencia Tipos

Variables Locales

Introduciendo LINQ

Page 19: Lenguaje Integrado de consultas LINQ

Fundamentos de LINQLenguaje Integrado de Consultas: LINQ

Page 20: Lenguaje Integrado de consultas LINQ

LINQ: Lenguage Integrated Query

• Lenguaje de consulta universal de primer orden en C# y VB9▫ Reducir el conocimiento de distintas formas de consulta.▫ Parecido a lo que ya conocemos : SQL▫ Basado en Lambda Cálculo, Tipado fuerte, Ejecución

retrasada (deferred) Utiliza características nuevas del lenguaje como: Inferencia de tipos, Tipos anónimos, Métodos extensores y Inicialización de objetos

▫ Altamente extensible• Múltiples proveedores

Objects, XML, DataSets, SQL, Entities WMI, Sharepoint, Excel… incluso para Google, Flickr,

Amazon

Page 21: Lenguaje Integrado de consultas LINQ

Language INtegrated Query (LINQ)

LINQ enabled data sources

LINQTo Objects

Objects

LINQTo XML

<book> <title/> <author/> <price/></book>XML

LINQ enabled ADO.NET

LINQTo DataSets

LINQTo SQL

LINQTo Entities

Relational

Others…VB C#

.NET Language-Integrated Query

Page 22: Lenguaje Integrado de consultas LINQ

Arquitectura de LINQ

System.Linq.EnumerableBasado en delegados

Fuente implementaIEnumerable<T>

var query = from p in passengers where p.Citizenship== “ES" select p

System.Linq.QueryableBasado en árbol de

expresión

Fuente implementaIQueryable<T>

SQL DataSetsObjetos EntitiesXML

Page 23: Lenguaje Integrado de consultas LINQ

Expresión de Consulta

from id in source{ from id in source | join id in source on expr equals expr [ into id ] | let id = expr | where condition | orderby ordering, ordering, … } select expr | group expr by key[ into id query ]

Empieza con from

Cero o más from, join, let, where, o orderby

Termina conselect o group

by

Continuación into opcional

Page 24: Lenguaje Integrado de consultas LINQ

Expresiones de ConsultaProyección Select <expr>Filtrado Where <expr>, DistinctComprobación

Any(<expr>), All(<expr>)

Union <expr> Join <expr> On <expr> Equals <expr>

Agrupación Group By <expr>, <expr> Into <expr>, <expr>Group Join <decl> On <expr> Equals <expr> Into <expr>

Agregación Count(<expr>), Sum(<expr>), Min(<expr>), Max(<expr>), Avg(<expr>)

Partición Skip [ While ] <expr>, Take [ While ] <expr>Conjunto Union, Intersect, ExceptOrdenación Order By <expr>, <expr> [ Ascending |

Descending ]

Page 25: Lenguaje Integrado de consultas LINQ

Operadores de ConsultaExpresión de consulta de Linq

Where(), Select(), SelecMany(), OrderBy(), ThenBy(), OrderByDescending(), ThenByDescending(), GroupBy(), Join(), GroupJoin()

Partición Take(), Skip(), TakeWhile(), SkipWhile()Conjunto Distinct(), Union(), Intersect(), Except()Conversión ToArray(), ToList(), ToDictionary(), ToLookup(),

AsEnumerable(), Cast<T>(), OfType<T>()Generación Range(), Repeat<T>(), Empty<T>(), Concat(),

Reverse()Cuantificación Any(), All(), Contains(), SequenceEqual()Elementos First(), Last(), Single(), ElementAt(), DefaultIfEmpty().

{método}OrDefault()Agregados Count(), LongCount(), Max(), Min(), Sum(), Average(),

Aggregate()

Page 26: Lenguaje Integrado de consultas LINQ

LINQ to ObjectsLenguaje Integrado de Consultas: LINQ

Page 27: Lenguaje Integrado de consultas LINQ

LINQ To Objects• Aplicable en colecciones genéricas y arrays que

están en memoria (heap)• Métodos extensores para colecicones y arrays

▫ Using System.Linq;• Las expresiones de consulta devuelven

IEnumerable<T>• Fundamental para gestionarlas de modo flexible

Page 28: Lenguaje Integrado de consultas LINQ

Ejemplos de consultas

Page 29: Lenguaje Integrado de consultas LINQ

LINQ to XMLLenguaje Integrado de Consultas: LINQ

Page 30: Lenguaje Integrado de consultas LINQ

XML en .Net Framework• Clases XmlTextReader y XmlTextWriter

▫ L/E secuencial: Eficiente pero complejo• Serialización y Deserialización:

System.Xml.Serialization▫ Atributos en clases, S/D contra streams (ficheros,

memoria…)• Clases XmlDocument, XmlNode … en System.Xml

▫ Implementan un DOM por árboles• Ahora: LINQ To XML

▫ Extensión de LINQ de .Net▫ Simple, Flexible, Potente, nuevo DOM.▫ Manipulación y consulta con LINQ

Page 31: Lenguaje Integrado de consultas LINQ

LINQ To XML• Importando System.Xml.Linq• Nuevo DOM:

▫ Construcción funcional: XElement• Independencia del documento

▫ Permite crear fragmentos XML sin asociarlos a un XDocument

• Texto como valor▫ Hojas del árbol XML se convierten a tipos por valor

de .Net

Page 32: Lenguaje Integrado de consultas LINQ

Clase XElement

.Load() / .Save() Cargan o Guardan de un stream un documento XML

.Elements() Secuencia de elementos contenidos

.ElementsBeforeSelf(), .ElementsAfterSelf()

Elementos “hermanos” anteriores o posteriores en el mismo nivel del árbol

.Descendants{AndSelf}()

Secuencia aplanada de todos los elementos hijos

.Ancestors{AndSelf}()

Secuencia aplanada de todos los elementos padres

.Attributes() Atributos del elemento

• Los métodos están sobrecargados para localizar elementos concretos.

• Métodos más representativos

Page 33: Lenguaje Integrado de consultas LINQ

Creación de documentos• Directamente con XElement

XElement contacts = new XElement("Contacts", new XElement("Contact", new XElement("Name", "Patrick Hines"), new XElement("Phone", "206-555-0144", new XAttribute("Type", "Home")), new XElement("phone", "425-555-0145", new XAttribute("Type", "Work")), new XElement("Address", new XElement("Street1", "123 Main St"), new XElement("City", "Mercer Island"), new XElement("State", "WA"), new XElement("Postal", "68042"))));contacts.Save("contacts.xml");

Page 34: Lenguaje Integrado de consultas LINQ

Consultas• Load(uri) (archivos, http…)• Métodos Elements, Attributes, Element, Attribute …• Se puede utilizar Xpath (método

XPathSelectElements())

XElement element = XElement.Load(Server.MapPath(@"~\XmlFiles\rssMiniNova.xml"));…XElement element = XElement.Load(@"http://www.mininova.org/rss.xml?cat=8");

var query = from i in element.Elements("channel").Elements("item") select new { Title = i.Element("title").Value, Posted = DateTime.Parse(i.Element("pubDate").Value), Size = Convert.ToDecimal(i.Element("enclosure").

Attribute("length").Value) Link = i.Element("enclosure").Attribute("url").Value, Category = i.Element("category").Value };

Page 35: Lenguaje Integrado de consultas LINQ

Transformación de documentos• Utilizando Linq y XElement• Método Save(stream/fichero… ), ToString() …

XElement nuevo = new XElement("TSAInformationForm", new XAttribute("Date", DateTime.Now), new XElement("SourceID", "883829HFGHMT"), new XElement("PassengerList", from p in pasajeros select new XElement("Passenger", new XAttribute("DocumentId", p.Id), new XElement("Name", p.Name), new XElement("Country", p.Citizenship), new XElement("Flight", new XAttribute("Code",p.Code), new XElement("ArrivalDate",p.Arrival)

))));

nuevo.Save("TsaSendFile.xml");

<TSAInformationForm Date="..."> <SourceID>...</SourceID> <PassengerList> <Passenger DocumentId="..."> <Name>..</Name> <Country>..</Country> <Flight Code="..."> <ArrivalDate>..</ArrivalDate> </Flight> </Passenger> ... </PassengerList> </TSAInformationForm>

Page 36: Lenguaje Integrado de consultas LINQ

LINQ to Entities• Arquitectura Entitiy Framework (EF)• LINQ to Entities • Ejemplos

Page 37: Lenguaje Integrado de consultas LINQ

Arquitectura de EF•OR/M + Objetos de Servicio

▫Soporte de varios SGDB: EntityClientProvider

▫Herramientas y lenguaje para mapeado▫Modelo Conceptual: EntityObject▫Contextos tipados: ObjectContext▫Gestión de Entidades:

ObjectStateManager▫Consulta: eSQL y LINQ To Entities

Page 38: Lenguaje Integrado de consultas LINQ

Patrón arquitectónico empresarial típico

UI / UICWebforms,

Console App,

ASP.NETWeb

Services

ADO.NET 3.0: Entity Framework

FachadaStateless,Short lived contexts

Modelo LógicoClases EntityObjects

Gestión Modelo

ObjectContext, ObjectStateManager

Oracle

SqlServer

Interface Lógica de negocio Almacén

ADO.NET 3.0

Def. Visual del Modelo

Archivo .EDMX | Edmgen.exe

EFDataProviderSqlServer, Oracle, MySQL, DB2, etc.

MetadataArchivos CSDL, MSL y SSDL

SGBDCSDL<Schema Namespace="BlogsSample.BusinessLogic.ADONET30.Model" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm"> <EntityContainer Name="BlogContext"> <EntitySet Name="BlogPosts" EntityType="BlogsSample.BusinessLogic.ADONET30.Model.BlogPost" /…MSL<?xml version="1.0" encoding="utf-8"?><Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS"> <EntityContainerMapping StorageEntityContainer="dbo" CdmEntityContainer="BlogContext"> <EntitySetMapping Name="BlogPosts"> <EntityTypeMapping TypeName="IsTypeOf(BlogsSample.BusinessLogic.ADONET30.Model.BlogPost)"> <MappingFragment StoreEntitySet="BlogPosts"> <ScalarProperty Name="BlogPostID" ColumnName="BlogPostID" />…

SSDL<?xml version="1.0" encoding="utf-8"?><Schema Namespace="BlogsSample.BusinessLogic.BlogsModel.Store" Alias="Self" ProviderManifestToken="09.00.3042" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl"> <EntityContainer Name="dbo"> <EntitySet Name="BlogComments" EntityType="BlogsSample.BusinessLogic.BlogsModel.Store.BlogComments" />

public partial class BlogContext : ObjectContext {… public ObjectQuery<BlogPost> BlogPosts { get { if ((this._BlogPosts == null)) { this._BlogPosts =

base.CreateQuery<BlogPost>("[BlogPosts]"); } return this._BlogPosts; } }… public void AddToBlogs(Blog blog) { base.AddObject("Blogs", blog); }

public partial class Blog : EntityObject { public static Blog CreateBlog(int blogID, string seriesTitle, bool needsReviewer) { Blog blog = new Blog(); blog.BlogID = blogID; blog.SeriesTitle = seriesTitle; blog.NeedsReviewer = needsReviewer; return blog; } public int BlogID { get { return this._BlogID; } set { this.OnBlogIDChanging(value); this.ReportPropertyChanging("BlogID"); this._BlogID = StructuralObject.SetValidValue(value); this.ReportPropertyChanged("BlogID"); this.OnBlogIDChanged(); } }

... }

public class Facade{ public static IList<Blog> GetAllBlogUpdatedSince(UpdatedSince period) { DateTime date = FacadeHelper.getPeriod(period);

using (BlogContext ctx = new BlogContext()) { IQueryable<Blog> blogs = from blog in ctx.Blogs where blog.BlogPosts.Any(p => p.BlogDate > date) select blog; return blogs.ToList<Blog>(); } }}

using BlogsSample.BusinessLogic.ADONET30;…protected void Button2_Click(object sender, EventArgs e){ GridView2.DataSource = Facade.GetAllBlogUpdatedSince( UpdatedSince.LastYear); GridView2.DataBind();}

Page 39: Lenguaje Integrado de consultas LINQ

Modelo Conceptual en EF• Clases prescriptivas

▫Structural Object > EntityObject ▫Gestión de identidad (EntityKey)▫Gestión de cambios (TrackingEntity event)▫Soporte para relaciones (EntityCollection)▫Estado (EntityState)▫Son clases parciales

• Posibilidad de clases IPOCO▫Implementar IEntityWithKey,

IEntityWithChangeTracker, IEntityWithRelationship

Page 40: Lenguaje Integrado de consultas LINQ

Object Context• Clase derivada (generada) de ObjectContext• Tipado Fuerte: Manipulación del Modelo Conceptual

▫ Consultas/Recuperación: Blogs: ObjectQuery;▫ Inserciones: .AddToBlog(Blog b); .AddObject(…), ▫ Borrado: .DeleteObject▫ Persistencia: .SaveChanges();

• Gestión de la conexión• Metadata (a partir de CSDL)• Almacen o caché en memoria de objetos• Tracking de estado objetos:

▫ .Attach(..), .Dettach(..) ▫ ObjectStateManager▫ MergeOption

Page 41: Lenguaje Integrado de consultas LINQ

ObjectStateManager•Seguimiento del estado de entidades•Gestiona entradas EntityStateEntry para

cada Entidad en almacen en memoria.▫Cuando se cargan (Query, Attach): Unchanged▫Cuando se crean (AddObject): Added▫Cuando se modifican: Changed▫Cuando se borran: Deleted▫Cuando se destruye el ObjectContext:

Detached▫Al aplicar ObjectContext.SaveChanges() en

Added, Changed, cambia a Unchanged.

Page 42: Lenguaje Integrado de consultas LINQ

Diseño: Entity FrameworkEntityObject ObjectContext

BloggerCtxBlogs: ObjectQueryBlogPosts: ObjectQueryAddToBlogs(…)AddToBlogPosts(…)Hereda:Attach(..)Dettach(..)Add(..)Delete(..),Refresh(..)SaveChanges(..) etc.

ObjectStateManager1Caché de EntidadesGestión de Identidad, estado ycambios en las Entidades

1 EntityStateEntryCurrentValuesOriginalValuesStateIsRelationship

Blog BlogPost*

BlogPostId: intBlogEntry: string…

EntityKey EntityState:Added, Deleted, Detached, Changed, UnchangedPropertyChanged

Page 43: Lenguaje Integrado de consultas LINQ

Consultas•Entity SQL

▫Dialecto SQL indep. de gestor con soporte para: Tipos enriquecidos, relaciones, herencia… Strings que se resuelven en tiempo de ejecución

•LINQ to Entities▫Todas las ventajas de LINQ (tipado fuerte,

expresiones lambda)▫Lenguaje que se resuelve en tiempo de

compilación▫Aprovechamos el tipado fuerte, la inferencia y el

Intellisense de Visual Studio▫Menos errores en ejecución

IQueryable<Blog> query = from posts in ctx.BlogPosts where posts.BlogDate > date select posts.Blogs;

ObjectQuery<Blog> query = ctx.CreateQuery<Blog>( "SELECT VALUE bp.Blogs FROM BlogPosts as bp WHERE bp.BlogDate > @date", new ObjectParameter("date",date));

Page 44: Lenguaje Integrado de consultas LINQ

LINQ To Entities• Diferencias con LINQ To Objects y To XML• Las consultas tienen el tipo ObjectQuery<T>

▫Implementa IQueryable<T> y no IEnumerable<T>▫Necesita Árboles de expresión para construir el

SQL final.• Cuando se enumeran los resultados:

▫query1.FirstOrDefault(), query1.ToList() …▫Se ejecuta la consulta SQL y devuelve un

IEnumerable<T>• No están disponibles todos los operadores de

Linq To Objects o To XML

Page 45: Lenguaje Integrado de consultas LINQ

Arquitectura de LINQ To Entities

Page 46: Lenguaje Integrado de consultas LINQ

Operadores disponiblesExpresión de consulta de Linq

Where(), Select(), SelecMany(), OrderBy(), ThenBy(), OrderByDescending(), ThenByDescending(), GroupBy(), Join(), GroupJoin()

Partición Take(), Skip()Conjunto Distinct(), Union(), Intersect(), Except()Conversión ToArray(), ToList(), ToDictionary(), ToLookup(),

AsEnumerable(), Cast<T>(), OfType<T>()Generación N/ACuantificación Any(), All()Elementos First(), Last(), ElementAt(). {método}OrDefault()Agregados Count(), LongCount(), Max(), Min(), Sum(), Average()

Page 47: Lenguaje Integrado de consultas LINQ

Cómo hacer una consulta• Establecer el contexto

▫Using (FlightContext ctx = new FlightContext()) { …}

• Dentro del contexto construír la consulta▫Obtener los IQueryable<T> del Contexto▫IQueryable<Flight> query =

from f in ctx.Flightswhere p.To==“MAD”select f;

• Ejecutar la consulta▫Con un operador de conversión

query.ToList(); query.FirstOrDefault() …

Page 48: Lenguaje Integrado de consultas LINQ

Otras consideraciones• Pensar la consulta con el modelo conceptual

▫ Navegar por las relaciones y no con joins• Los objetos recuperados dentro del contexto son

gestionados por el ObjectStateManager (tracking)• Cuando se cierra el contexto NO.• Carga Perezosa de relaciones (dentro de un contexto)

▫ ¡¡No nos lo vamos a traer todo!!▫ Si en el where se utiliza una relación, ésta se carga▫ Carga implícita

from f in ctx.Flights.Include(“Aircraft”) select f;▫ Carga explícita

if (!aflight.Aircraft.IsLoaded) aflight.Aircraft.Load();

Page 49: Lenguaje Integrado de consultas LINQ

Modelo ER

Page 50: Lenguaje Integrado de consultas LINQ

Modelo EF

Page 51: Lenguaje Integrado de consultas LINQ

RecursosLenguaje Integrado de Consultas: LINQ

Page 52: Lenguaje Integrado de consultas LINQ

Recursos• MSDN: http//Msdn.microsoft.com• 101 Linq Samples:

http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx • Blogs:

▫ ADO.NET Team Blog: http://blogs.msdn.com/adonet/ ▫ Blog de Dany Simons: http://blogs.msdn.com/dsimmons/ ▫ Blog de Unai Zorrilla: http://geeks.ms/blogs/unai/ ▫ Blog de Octavio Hdez.: http://geeks.ms/blogs/ohernandez/

• Libros:▫ “C# 3.0 y LINQ”, Octavio Hernández. Krasis Press 2007.

ISBN: 978-84-935489-1-9▫ “ADO.NET Entity Framework”, Unai Zorrilla, Octavio

Hernández, Eduardo Quintás. Krasis Press 2008. ISBN: 978-84-935489-9-5