Sunteți pe pagina 1din 31

Facultatea de Informatic Iai

Intoducere n LINQ

Dunca (tefan) Alexandra Ramona tefan Alexandru Bogdan

Introducere n LINQ

Acest material este distribuit sub licenta :

Attribution-Noncommercial-Share Alike 2.5 Generic Sunteti liberi sa :


mprtiti puteti copia, redistribui, imprumuta lucrarea.

adaptati puteti adapta lucrarea

Sub urmatoarele conditii :


nu puteti sa declarati lucrarea ca fiind realizata de dumneavoastra trebuie sa specificati cine este autorul

nu puteti folosi lucrarea in scopuri comerciale

daca modificati, construiti peste aceasta lucrare va trebui sa distribuiti produsul final sub acelasi tip de licenta

Atentie!
Aplicatiile oferite ca exemplu la acest material au fost create cu Microsoft Visual Studio 2008 Professional Edition. Limbajul ales pentru implementare a fost Visual C# 2008. Imaginile prezentate pot diferi fata de alte variante ale Visual Studio. Va rugam verificati site-ul Microsoft pentru o comparatie intre versiunile Visual Studio.

2|Pagina

Introducere n LINQ

Coninut:
Ce este LINQ De ce LINQ? LINQ i C# Fundamente LINQ LINQ to Objects
LINQ i irurile de caractere LINQ i structura de fiere LINQ i reflecia

LINQ to ADO.NET
LINQ to DataSet LINQ to SQL LINQ to Entities

LINQ to XML LINQ i ASP.NET Bibliografie

4 5 6 7 16 17 18 18 19 20 23 26 27 30 31

3|Pagina

Introducere n LINQ

Ce este LINQ
LINQ = Language INtegrated Query i nseamn Limbaj integrat de interogare a datelor. Mai exact LINQ poate fi folosit pentru a interoga date din obiectele .NET care implementeaza interfata IEnumerable<T>, din orice tip de baza de date relationala sau din fisiere XML. Pentru interograrea obiectelor .NET Framework exista LINQ to Objects, pentru bazele de date relationale LINQ to ADO.NET si pentru documentele XML LINQ to XML. LINQ a aparut din nevoia de a umple golul care se gasea intre un limbaj de programare orientat obiect si modul de acces la date (spre exemplu C# si ADO.NET), din dorinta de a unifica modul de acces la date, de a-l face la fel de simplu ca accesarea datelor dintr-o variabila. LINQ introduce conceptul de interogare direct in orice limbaj de programare din .NET Framework. LINQ a aparut prima data ca parte a limbajului de programare C , aflat in stadiul de cercetare la Microsoft Research. Prima lansare comerciala a LINQ a venit odata cu lansarea .NET Framework 3.5 si a Visual Studio 2008 in Noiembrie 2007. In momentul de fata se afla in dezvoltare la Microsoft Research PLINQ Parallel LINQ ca parte a proiectului Parallel FX Library. LINQ este independent de limbaj. Exista implementari LINQ si pentru : LINQ to JavaScript implementat de Chris Pietschmann PHPLinq implementat de Maarten Balliauw Quaere implementare a LINQ sub Java GLinq LINQ pentru accesul la date Google

.NET Language INtegrated Query


C# Visual Basic .NET Alte limbaje .NET

Surse de date suportate de LINQ

LINQ to Objects

LINQ to DataSet

LINQ to SQL

LINQ to Entities

LINQ to XML

<XML/>

Colectii de obiecte

Baze de date relationale

Documente XML

4|Pagina

Introducere n LINQ

De ce LINQ?
Ca dezvoltatori de software este greu sa negam faptul ca majoritatea timpului de programare il petrecem obtinand si manipuland date. Si cand vine vorba de date primul lucru care ne vine in minte sunt bazele de date relationale. Dar in acelasi timp datele pot fi stocate si in fisiere XML (provenite din servicii web, fisiere de configurare, DataSet-uri incarcate in memorie, etc.). Datele se pot gasi si in colectii in memorie (ex: o lista de intregi, un vector de denumiri, etc). Problema care apare este ca pentru a putea manipula diferite tipuri de date avem nevoie de diferite API-uri, care pana la varianta 3.5 a .NET Framework erau: System.Data.dll, System.Data.SqlClient.dll, etc. pentru date relationale, System.Xml.dll pentru date stocate in fisiere XML, System.Reflection.dll pentru acces la metadate, System.Array, System.Collections si System.Collections.Generic pentru accesul la datele din colectiile de obiecte. Cu toate ca aceste API-uri nu au nici un fel de problema, ba chiar se gasesc si se pot folosi in continuare, au dezavantajul ca fiecare prezinta modul sau de acces la date. LINQ vine sa suplineasca acest neajuns unificand modul de manipulare a datelor. Folosind LINQ putem crea in C# asa numitele query expressions interogari foarte similare cu cele din SQL folosindu-ne de operatorii speciali de interogare.

5|Pagina

Introducere n LINQ

LINQ i C#
Pentru a putea folosi facilitatile LINQ in C# avem nevoie de urmatoarele assembly-uri care trebuie incluse in lista de referinte a proiectului: System.Core.dll Definieste nucleul LINQ API. Este obligatoriu pentru a putea folosi LINQ. System.Data.Linq.dll Lucrul cu baze de date relationale (LINQ to SQL). System.Data.DataSetExtensions.dll O extensie care integreaza tipurile ADO.NET cu LINQ (LINQ to DataSet) System.Xml.Linq.dll Lucrul cu documentele XML (LINQ to XML)

In codul C# trebuie sa includem directiva :

pentru a avea acces la tipurile de date definite de LINQ.

6|Pagina

Introducere n LINQ

Fundamente LINQ
O interogare simpla
Sa consideram pentru urmatorul exemplu clasa Developer :

Daca am avea un vector de dezvoltatori si am vrea sa aflam care sunt dezvoltatorii care folosesc ca limbaj C# vom scrie urmatoarele:

Dupa cum putem observa interogarea LINQ este foarte asemanatoare cu o interogare SQL. Operatorul from se foloseste pentru a specifica sursa de date, where specifica conditia de filtrare, iar select selecteaza numele dezvoltatorului. Interogarile LINQ pot fi exprimate in doua moduri: fie ca query expressions asa cum am vazut mai sus sau ca invocare explicita a metodelor utilizate. Exemplu:

7|Pagina

Introducere n LINQ

Interogarile LINQ
Forma unei interogari LINQ este data de urmatoarele reguli : query-expression ::= from-clause query-body query-body ::= join-clause* (from-clause join-clause* | let-clause | where-clause)* orderby-clause? (select-clause | groupby-clause) query-continuation? from-clause ::= from itemName in srcExpr select-clause ::= select selExpr groupby-clause ::= group selExpr by keyExpr let-clause ::= let itemName = selExpr where-clause ::= where predExpr join-clause ::= join itemName in srcExpr on keyExpr equals keyExpr (into itemName)? orderby-clause ::= orderby (keyExpr (ascending | descending)?)* query-continuation ::= into itemName query-body

Operatorii de interogare
Pentru exemplificare ne vom folosi de LINQ to Objects pe urmatoarea structura de date:

8|Pagina

Introducere n LINQ WHERE Operatorul where se foloseste pentru filtrarea datelor de iesire asemanator cu cel din SQL. Pentru clauze mai sofisticate este obligatoriu a se folosi varianta cu invocarea metodei, deoarece in query expression nu se pot defini decat filtre simple. SELECT Operatorul select face proiectia datelor pe campurile pe care le primeste ca parametru. Exemplu:

SELECTMANY Asemanator cu select, doar ca SelectMany returneaza varianta flat a rezultatului : IEnumerable<T> in loc de IEnumerable<T[]>. Nu poate fi folosit ca si query expression ci doar sub forma de invocare explicita a metodei. Exemplu:

ORDERBY si ORDERBYDESCENDING Sunt folositi pentru ordonarea rezultatelor dupa un camp specificat ca paramentru. ORDERBYDESCENDING nu poate fi folosit ca si query expression ci doar sub forma de invocare explicita a metodei. Exemplu:

THENBY si THENBYDESCENDING Sunt folositi atunci cand este nevoie de ordonare dupa mai mult de un camp. Nu poate fi folosit ca si query expression ci doar sub forma de invocare explicita a metodei. In cazul in care se specifica de mai multe ori aceeasi cheie de sortare rezultatele pot fi nedeterministe (rezultate diferite la fiecare rulare a query-ului). Exemplu:

9|Pagina

Introducere n LINQ REVERSE Returneaza lista de rezultate in ordine inversa (ultimul item devine primul). Nu poate fi folosit ca si query expression ci doar sub forma de invocare explicita a metodei. Exemplu:

GROUPBY Grupeaza rezultatele in functie de un anumit criteriu Exemplu:

JOIN Se foloseste pentru a face legatura intre date din mai multe surse (ex: tabele dintr-o baza de date relationala) Exemplu:

Asemanator expresia join poate fi exprimata si sub forma unui query expression:

Spre deosebire de SQL, ordinea in care sunt puse campurile dupa care se face join (cu ajutorul lui equals) este foarte importanta. In cazul in care nu se respecta ordinea, compilatorul C# va returna urmatoarea eroare : The name 'p' is not in scope on the left side of 'equals'. Consider swapping the expressions on either side of 'equals'. D:\Source Code\Visual C#\LinqTutorial\LinqTutorial\Program.cs

10 | P a g i n a

Introducere n LINQ GROUPJOIN Se foloseste in cazurile LEFT OUTER JOIN sau RIGHT OUTER JOIN . Diferenta fata de JOIN este la selectorul de proiectie. In GROUPJOIN trebuie sa specificam o instanta a IEnumerable<T> fata de un obiect simplu in cazul JOIN. Rezultatul va fi o secventa ierarhica de rezultate. Exemplu:

Pentru a putea afisa rezultatele acestei interogari vom folosi o secventa de forma:

Varianta sub forma de query expression a lui GROUPJOIN se realizeaza cu o clauza JOIN ... INTO:

DISTINCT Se foloseste atunci cand dorim sa evitam inregistrarile duplicate. Nu poate fi folosit ca si query expression ci doar sub forma de invocare explicita a metodei. Exemplu:

11 | P a g i n a

Introducere n LINQ UNION, INTERSECT si EXCEPT Se folosesc ca operatorii clasici pe multimi. Compararea se face cu ajutorul metodelor GetHashCode() si Equals() sau cu un comparator daca acesta se specifica. Exemplu:

COUNT si LONGCOUNT Se folosesc atunci cand se doreste numararea rezultatelor obtinute de catre query. Exemplu:

SUM Se foloseste pentru adunarea valorilor unui camp. Tipuri de date suportate : int, int?, long, long?, float, float?, double, double?, decimal, and decimal? (unde ? defineste tipuri Nullable; ex: int? =
Nullable<System.Int32>).

Exemplu:

MIN si MAX Se folosesc pentru determinarea valorilor minime sau maxime dintr-un sir de valori. La fel ca si SUM se poate folosi pe tipurile numerice sau pe tipurile care implementeaza interfata IComparable<T>. In cazult in care tipul T nu implementeaza IComparable atunci se va arunca o exceptie de tipul ArgumentException cu mesajul At least one object must implement IComparable. Exemplu:

AVERAGE Se foloseste pentru calcularea mediei aritmetice. Se poate aplica peste tipurile numerice. Daca tipul numeric este int sau long rezultatul este de tip double. Asemanator si pentru variantele Nullable. In rest tipul rezultat este acelasi cu tipul expresiei numerice. Daca valoarea calculata este mai mare decat maximul tipului rezultat atunci se va arunca o exceptie de forma OverflowException. Exemplu:

12 | P a g i n a

Introducere n LINQ AGGREGATE Primeste ca parametru o functie pe care o apleaza repetitiv cat timp se indeplineste o conditie. Valoarea calculata de functie este stocata intr-un acumulator (suma valorilor). La final operatorul returneaza valoarea acumulatorului. Exemplu:

RANGE Primeste doi parametri : start si count. Returneaza o lista de intregi de lungime count pornind de la start si incrementand la fiecare pas cu 1. Exemplu:

REPEAT Primeste doi parametrii : unul de tip generic T si count de tip int. Returneaza o lista cu elementul de tip T repetat de count ori. Toate valorile returnate sunt referinte la aceeasi valuare si nu copii. Exemplu:

13 | P a g i n a

Introducere n LINQ EMPTY Operatorul genereaza o lista goala de tipul primit ca parametru. Poate fi util la initializarea secventelor empty. Exemplu:

ANY Operatorul returneaza true daca macar un element se gaseste in sursa si false daca secventa sursa este goala. Pentru optimizarea executiei returneaza o valoare imediat ce un rezultat este disponibil. Exemplu:

ALL Operatorul returneaza true daca toate elementele din sursa specificata indeplinesc conditia. Daca sursa specificata nu contine nici un element atunci ALL va returna true; Exemplu:

CONTAINS Operatorul returneaza true daca sursa specifica contine elementul primit ca parametru. In cazul LINQ for Objects incearca apelarea metodei Contains daca tipul primit ca parametru implementeaza interfata ICollection<T>. Daca nu atunci va compara cu ajutorul comparatorului specificat ca parametru. Exemplu:

14 | P a g i n a

Introducere n LINQ TAKE Primeste ca parametru o secventa de elemente si count . Returneaza primele count elemente din secventa. Daca count are valoare negativa atunci rezultatul va fi gol. Exemplu:

TAKEWHILE Asemanator cu TAKE doar ca verifica o conditie si returneaza doar elementele care satisfac acea conditie. SKIP si SKIPWHILE Asemanator cu TAKE si TAKEWHILE cu diferenta ca produc rezultate abia cand conditia de test devine falsa. FIRST si FIRSTORDEFAULT Returneaza primul element din sursa. Diferenta intre FIRST si FIRSTORDEFAULT este ca FIRSTORDEFAULT returneaza primul doar daca exista fara sa genereze nici un fel de exceptie. In cazul in care secventa este vida returneaza valoarea default a tipului: default<T>. Exemplu:

LAST si LASTORDEFAULT Asemanator cu FIRST si FIRSTORDEFAULT doar ca returneaza ultimul element din lista. SINGLE si SINGLEORDEFAULT Se foloseste atunci cand se doreste selectarea unei singure valori sau a unui element unic. Exemplu:

ELEMENTAT si ELEMENTATORDEFAULT Primeste ca parametru index si returneaza elementul de pe pozitia specificata. Daca valoarea parametrului index este negativa se arunca o exceptie de forma ArgumentOutOfRangeException. Exemplu:

DEFAULTIFEMPTY Returneaza valoarea default atunci cand secventa primita ca parametru este vida. Poate fi util atunci cad se fac unit-uri de testare cod. CONCAT Concateneaza rezultatele obtiunite din doua interogari LINQ. SEQUENCEEQUAL Operator care testeaza daca doua secvente rezultate sunt egale. Compararea se face pe baza metodelor GetHashCode() si Equals() sau cu un comparator daca acesta se specifica.

15 | P a g i n a

Introducere n LINQ

LINQ to Objects
LINQ to Objects este modulul LINQ care se ocupa de interogarea colectiilor de date stocate in memorie.

Ce putem interoga?
LINQ poate interoga orice tip de date din .NET Framework care implementeaza interfata IEnumerable<T>. Astfel de tipuri de date sunt denumite secvente in vocabularul LINQ. Toate colectiile generice definite de .NET Framework 2.0 implementeaza interfata IEnumerable<T>. Acestea sunt: System.Collections.Generic.List<T> System.Collections.Generic.LinkedList<T> System.Collections.Generic.Queue<T> System.Collections.Generic.Stack<T> System.Collections.Generic.HashSet<T> System.Collections.ObjectModel.Collection<T> System.ComponentModel.BindingList<T> System.Collections.Generic.Dictionary<TKey,TValue> System.Collections.Generic.SortedDictionary<TKey, TValue> System.Collections.Generic.SortedList<TKey, TValue> System.String privit ca IEnumerable<char> dar fara IntelliSense

Orice tip de date definit de programator poate fi interogat daca implementeaza interfata IEnumerable<T>. In cazul in care nu implementeaza aceasta interfata exista solutii de interogare folosind operatorii Cast si OfType. Operatii suportate: Restrictionare Proiectie Partitionare Join Ordonare Groupare Operatii pe multimi Conversie Testarea egalitatii Generare Cuantificare Agregare Aceste operatii sunt posibile folosindu-se operatorii definiti in sectiunea Fundamente LINQ.

16 | P a g i n a

Introducere n LINQ

LINQ si sirurile de caractere


LINQ poate fi folosit pentru a transforma siruri de caractere sau colectii de tip string. Este foarte util cu date semi-structurate in fisiere text. Interogarile LINQ pot fi combinate cu functiile clasice de lucru cu siruri de caractere sau cu expresii regulate. Functia Split poate fi folosita (spre exemplu) pentru a imparti un text in cuvinte si apoi se pot interoga cuvintele separate. Cum putem: 1. numara aparitiile unui cuvant intr-un string

2. cautam anumite caractere intr-un string

3. folosi LINQ cu expresii regulate

4. reordonam campurile intr-un CSV

17 | P a g i n a

Introducere n LINQ

LINQ i structura de fiere


Multe dintre operatiile asupra structurii de fisiere sunt defapt, interogari. Astfel putem folosi LINQ pentru a exprima interogarile. Cum putem: 1. cauta fisiere cu anumite atribute

2. grupa fierele dupa extensie

LINQ si reflectia
API-ul de reflectie din libraria de clase .NET Framework poate fi utilizat pentru a examina metadatele dintr-un assembly .NET si crea colectii de tipuri, membrii, parametrii, etc in acel assembly. Toate aceste colectii implementeaza interfata IEnumerable si astfel pot fi interogate folosind LINQ.

18 | P a g i n a

Introducere n LINQ

LINQ to ADO.NET
LINQ to ADO.NET consta in trei tehnologii separate: LINQ to DataSet LINQ to SQL LINQ to Entities (inca in stadiu de dezvoltare) LINQ to DataSet permite interogari complexe si optimizate pentru DataSet-uri incarcate in memorie. LINQ to SQL permite interogarea directa a bazelor de date SQL Server. LINQ to Entities permite interogari asupra Entity Data Model. Acesta este un model conceptual care poate fi utilizat pentru a modela date dintr-un domeniu particular astfel incat aplicatiile sa interactioneze cu datele la fel cum interactioneaza cu obiectele.

19 | P a g i n a

Introducere n LINQ

LINQ to DataSet
Ce este un DataSet?
DataSet-ul este unul din cele mai folosite componente ADO.NET. Este elementul cheie al modelului de lucru in mod deconectat oferit de ADO.NET. Acesta va da posibilitatea sa pastrati in memoria locala o copie a unei surse de date (sau a unei parti din aceasta), sa o actualizati si apoi sa o trimiteti spre procesare serverului de baze de date. DataSet-ul se integreaza cu controalele WindowsForms sau WebForms printr-o proprietate numita databinding (legatura de date). DataSet-ul este organizat asemanator cu o baza de date (este format din tabele cu coloane, inregistrari dar si cu relatii intre aceste tabele). Cea mai importanta functie a DataSet-ului este acea ca permite lucrul deconectat cu bazele de date, reducand traficul pe retea si incarcarea serverului de baze de date. Sa luam spre exemplificare o aplicatie web ASP.NET care foloseste date dintr-o baza de date. De multe ori o parte importanta din datele acestei aplicatii nu se modifica frecvent si este folosita la comun de mai multi utilizatori. Aceasta portiune de date poate fi tinuta intr-un DataSet in cache-ul serverului web si astfel se reduce incarcarea bazei de date si viteza de executie a aplicatiei web creste semnificativ. Cu toate acestea, DataSet-ul are capabilitati limitate de interogare. Metoda Select poate fi folosita pentru filtrarea si sortarea datelor iar GetChildRows si GetParentRow se folosesc pentru navigarea ierarhica. Pentru ceva mai complex insa, programatorul trebuie sa scrie o interogare specializata. Asta poate rezulta in aplicatii cu viteza scazuta de executie si care sunt greu de intretinut. Aici intervine LINQ to DataSet pentru a usura munca programatorului. Expresiile de interogare sunt scrise in limbajul de programare, se creste productivitatea deoarece verificarea sintaxei si consistena tipurilor sunt verificate la compilare de catre Visual Studio si se ofera suport IntelliSense pentru LINQ.

20 | P a g i n a

Introducere n LINQ

Cum interogam date folosind LINQ to DataSet?


Inainte de a putea interoga un DataSet acesta trebuie populat cu date. Sunt mai multe metode de a face acest lucru: folosind un DataAdapter sau folosind LINQ to SQL. Dupa ce datele au fost introduse se poate incepe interogarea lor folosind LINQ. Interogarile sunt similare cu cele de la celelalte tipuri LINQ. Interogarile se pot realiza asupra unuia sau mai multor tabele din DataSet folosind Join si GroupJoin. Interogarile LINQ sunt suportate pe ambele tipuri de DataSet-uri (tipizate si netipizate). Daca se cunoaste schema DataSet-ului la momentul dezvoltarii aplicatiei atunci se recomanda un DataSet tipizat (interogarile sunt mai usor de realizat si sunt mai lizibile). Pe langa operatorii standard de interogare definiti de LINQ, LINQ to DataSet vine cu o serie de operatori specifici penru interograrea unui set de obiecte DataRow. Aceste extensii specifice DataSeturilor includ operatori de compararea a unor secvente de inregistrari si metode care permit accesul la valorile coloanelor dintr-un DataRow. Pentru exemplificare vom folosi acelasi exemplu de la LINQ to Objects, doar ca acum datele sunt stocate intr-un DataSet tipizat. Datele sunt importate dintr-o baza de date MS SQL Server 2005 Compact Edition. DataSetul este urmatorul:

21 | P a g i n a

Introducere n LINQ

1. Interogari asupra unui singur tabel Pentru acesta va trebui mai intai sa ne definim o variabila de tip DataTable si sa o incarcam cu datele din DataSet. Aceasta se realizeaza in maniera urmatoare:

Apoi interogam dupa toate cartile de la editura Apress:

2. Interogari din mai multe tabele

Selectam cartile care au fost comandate:

22 | P a g i n a

Introducere n LINQ

LINQ to SQL
Folosind LINQ to SQL putem accesa baze de date SQL la fel cum am accesa colectii de date din memorie. In LINQ to SQL modelul de date al bazei de date relationale este mapat la un model de obiecte in limbajul de programare in care lucram. Cand aplicatia ruleaza, interogarile LINQ to SQL asupra obiectelor din modelul definit anterior sunt traduse in interogari SQL si trimise la baza de date pentru a fi executate. Cand baza de date returneaza rezultatele, acestea sunt traduse inapoi in obiecte cu care putem lucra in limbajul de programare ales. Daca folosim Visual Studio atunci avem la dispozitie Object Relational Designer care ofera o interfata utilizator pentru implementarea multor din facilitatile LINQ to SQL. Pentru a avea acces la acest designer va trebui sa includem in proiectul nostru un obiect de tipul LINQ to SQL Classes ca in exemplul de mai jos. Acesta ne va crea un fiser DBML (DataBase Markup Language) in care vor fi stocate maparile si va deschide Object Relational Designer.

Dupa acesta tot ce ramane de facut este sa tragem pe suprafata designer-ului din Server Explorer tabelele definite in baza de date. Automat vor fi create pentru noi clasele corespunzatoare acestor tabele. Tot aici putem defini si relatii intre clasele asemanator cu relatiile dintr-o baza de date. Suprafata Designerului va arata cam asa:

23 | P a g i n a

Introducere n LINQ Clasele create se gasesc in fisierul : <nume_fisier_DBML>.Designer.cs si au un atribut special: [Table(Name="dbo.<nume_tabel>")] .

Cum se face maparea?


Maparea in LINQ to SQL se face dupa tabelul urmator: Obiecte LINQ to SQL Clasa Membru Asociere Metoda Modelul relational Tabel Coloana Relatie tip Cheie Straina (Foreign Key) Procedura stocata sau functie

Clasa DataContext
Aceasta clasa este sursa tuturor entitatilor mapate peste o conexiune la baza de date. Urmareste schimbarile facute la fiecare din entitati si mentine si un identity cache care garanteaza ca entitatile primite ca rezultat de mai multe ori de la baza de date sunt referite de acelasi obiect (integritatea datelor). Un DataContext este definit pentru a fi utilizat pentru o singura unitate de lucru. Programatorul stabileste ce inseamna acest lucru. Un DataContext este usor de creat si nu consuma multe resurse. Clasa DataContext contine, printre altele si urmatoarele metode: CreateDatabase, DatabaseExists, DeleteDatabase, ExecuteCommand, ExecuteQuery pentru operatii asupra bazei de date (cu SQL DDL si SQL DML). Cea mai importanta utilizare a clasei DataContext este totusi faptul ca asupra unui obiect de acest fel se executa interogarile LINQ to SQL. Cand se creaza clasele intr-un DataContext acesta concateneaza automat un s la finalul numelui tabelului.

Ce interogari pot realiza cu LINQ to SQL ?


1. Selectie (proiectie)

24 | P a g i n a

Introducere n LINQ 2. Insertie

3. Modificare

4. Stergere

25 | P a g i n a

Introducere n LINQ

LINQ to Entities (inca in stadiu de dezvoltare)


EDM (Entity Data Model) este o specificatie pentru definirea datelor utilizate de aplicatiile construite peste Entity Framework. Aplicatiile care folosesc EDM definesc entitati si relatii in domeniul aplicatiei intr-o schema de design. Acesta schema este folosita pentru a construi clase folosite mai apoi in cod. Structurile care stocheaza aceste date sunt definite intr-o schema de stocare. O specificatie de mapare conecteaza cele doua scheme. Schema de mapare conecteaza efectiv structurile de date din memorie cu structuri de stocare permanente (ex: Baze de date). Entitatile definite de EDM pot fi citite (deserializate) cu ajutorul unui DataReader sau pot fi materializate ca obiecte. Obiectele materializate sunt programabile in limbajele de programare suportate de CLR si sunt actualizate si salvate fara a se folosi SQL sau orice alta sintaxa de baza de date. EDM furnizeaza tipurile de baza si tipuri relatie folosite in schemele EDM si in specificatiile de mapare. Programatorii pot extinde aceste tipuri pentru a se conforma cu specificatiile aplicatiilor lor. Fiecare din paradigmele folosite pentru a manipula datele are punctele lui forte. Modelul relational este optimizat pentru stocare si regasire eficienta. XML suporta schimb de date intre platforme. Programarea orientata-obiect este standardul acceptat pentru dezvoltarea de aplicatii. Toate aceste modele sunt utile dar pentru a trasfera date intre ele poate cere multe linii de cod care nu au nici o legatura cu scenariul definit de aplicatie. Entity Framework permite dezvoltatorilor sa lucreze cu date sub forma unor clase, obiecte, proprietati, fara sa fie nevoie sa se gandeasca la tabelele si coloanele din baza de date unde sunt stocate informatiile. Cu ajutorul infrastructurii Object Services din Entity Framework, ADO.NET 3.0 expune un model conceptual al datelor, incluzand date relationale precum si obiecte din mediul .NET . Aceasta face din acest strat (Object Services) o tinta ideala pentru LINQ. Tehnologia LINQ to Entities permite dezvoltatorilor sa creeze interogari felxibile si stronglytyped asupra contextului Entity Framework cu ajutorul expresiilor LINQ si a operatorilor standard de interogare LINQ. Mediul .NET se ocupa de tratarea erorilor de sintaxa, ca si erori in tipurile de date sau in numele membrilor, reducand potentialele probleme legate de tipuri de date intre EDM si aplicatie. Clasa ObjectContext este clasa cu ajutorul carora obiectele definite de Entity Data Model pot fi accesate ca obiecte CLR. Programatorul construieste o instanta generica a clasei ObjectQuery cu ajutorul ObjectContext. Obiectul de tip ObjectQuery reprezinta interogarea care returneaza colectia de obiecte. Obiectele returnare sunt updatabile si sunt localizate in contextul de obiecte.

Informatiile din acesta sectiune sunt bazate pe ADO.NET Entity Framework Beta 3 asa cum se gaseste pe site-ul Microsoft la data: Aprilie 2008. Pentru informatii actualizate va rugam accesati site-ul: http://www.microsoft.com

26 | P a g i n a

Introducere n LINQ

LINQ to XML
Tehnologia XML a devenit extrem de folosita in lumea de astazi, fie ca o intalnim in documente office, in fisiere de configurare, pe Internet sau in baze de date. Cu toate acestea, din punctul de vedere al dezvoltatorului e destul de greoi lucrul cu documente XML. Exista multe API-uri de lucru cu XML, cum ar fi: DOM, XSLT, XQuery dar fiecare prezinta modul specific de lucru. LINQ to XML vine sa rezolve aceasta problema. LINQ to XML ofera un mod de lucru asemanator cu DOM dar in acelasi timp si cu XQuery/XPath intr-un mod unificat de programare intr-unul din limbajele platformei .NET . Chiar daca difera ca sintaxa de XQuery sau XPath, LINQ ofera aceasi functionalitate intr-o maniera puternic tipizata. LINQ to XML poate fi privit din doua puncte de vedere diferite: unul ca un mod consistent de acces la date asemanator cu celelalte din familia LINQ dar si ca un API de lucru cu documente XML aflate in memorie si care ofera toate functionalitatile DOM, plus cateva functii cheie din XPath si XSLT. LINQ to XML se adreseaza diferitelor categorii de dezvoltatori. Avantajul acestei tehnologii este ca permite interogari similare cu cele SQL. Interogarile sunt succinte dar in acelasi timp puternice, acest lucru ducand la o crestere a productivitatii.

Clasele LINQ to XML


XObject XDeclaration XName XNamespace

XNode

XAttribute

XCData

XText

XComment

XContainer

XDocumentType

XProcessingInstruction

XDocument

XElement

Clasa XAttribute XCData XComment XContainer XDeclaration XDocument XDocumentType

Semnificatie Atribut XML Nod XML de tip Cdata Comentariu XML Clasa abstracta pentru nodurile de tip Container (contin alte noduri) Declaratie XML Document XML XML Document Type Definition (DTD) 27 | P a g i n a

Introducere n LINQ XElement XName XNamespace XNode XProcessingInstruction XText Element XML Numele elementelor de tip XElement si XAttribute Spatiul de nume pentru elemente XElement si XAttribute Clasa abstracta pentru toate nodurile XML Instructiune de procesare XML Nod de tip text. Nu e prea folosita in practica.

LINQ to XML vs. DOM


In DOM un document XML este entitatea de baza fara de care nu putem lucra. LINQ to XML ne permite sa cream elemente XML fara a fi nevoie de un obiect de tip document. Modelul de obiecte din LINQ to XML ne pune la dispozitie un document XML pentru a-l folosi in cazul in care avem nevoie (spre exemplu sa punem un comentariu sau o instructiune de procesare la inceputul documentului). In rest se creaza XML Infoset-ul in memorie. LINQ to XML DOM

In LINQ to XML codul pe care trebuie sa-l scriem este mult mai putin fata de DOM si are structura foarte asemanatoare cu cea din documentul XML. LINQ to XML DOM

In lucrul cu documente XML cele mai importante se dovedesc a fi elementele XML si atributele. LINQ to XML ne permite sa lucram in mod direct cu acestea. Putem serializa direct in fisiere (sau orice alt stream) obiectele de tip XElement sau le putem incarca de acolo. Clasa XDocument o folosim doar daca avem nevoie sa punem comentarii sau instructiuni de procesare la inceputul documentului.

28 | P a g i n a

Introducere n LINQ

Cum putem sa
1. incarcam XML dintr-un fisier

Incarcarea se poate face din fisier, TextReader sau XmlReader. 2. parsam XML dintr-un string

Metoda Parse arunca o exceptie de tipul System.Xml.XmlException in cazul in care sirul parsat nu este corect XML. 3. serializam un XElement sau un XDocument

Serializarea din XElement introduce automat in documentul XML creat si prologul. Pentru a omite includerea acestuia trebuie sa folosim clasa XmlWriterSettings. Serializarea se face in fisiere si obiecte de tipul TextWriter si XmlWriter. 4. interogam un document XML

5. sortam rezultatele unei interogari

6. adaugam un nou element Folosind XElement.Add() sau XAttribute.Add() 7. modificam valoarea unui element Folosind XElement.Value sau XElement.Replace()

29 | P a g i n a

Introducere n LINQ

LINQ si ASP.NET
LINQ este o tehnologie noua care poate fi folosita cu succes in aplicatiile web create cu ASP.NET. Orice aplicatie web are la baza o sursa de date, fie ea in format XML, baza de date relationala sau altul. LINQ ofera capacitati de interogare si manipulare a datelor intr-un mod rapid si eficient. Toate controalele din ASP.NET 3.5 suporta ca sursa de date o interogare LINQ. Prin intermediul proprietatii DataBinding se seteaza sursa de date care vor fi afisate de catre control. Exemple de controale ASP.NET LINQ-enabled: asp:RadioButtonList asp:CheckBoxList asp:DropDownList asp:Listbox asp:DataGrid

30 | P a g i n a

Introducere n LINQ

Bibliografie

Joseph C. Rattz : Pro LINQ: Language Integrated Query in C# 2008, Apress 2007 Fabrice Marguerie, Steve Eichert, Jim Wooley, si Matt Warren : LINQ in Action, Manning 2008 Scott Klein : Proffesional LINQ (Programmer to Programmer) , Wrox 2008 Andrew Troelsen : Pro C# 2008 and the .NET 3.5 Platform, Apress 2007 Paolo Pialorsi and Marco Russo : Introducing Microsoft LINQ, MSPress 2007 Matthew MacDonald si Mario Szpuszta : Pro ASP.NET 3.5 in C# 2008, Apress 2008 Scott Gus Blog : http://weblogs.asp.net/scottgu/archive/tags/LINQ/default.aspx http://msdn2.microsoft.com/en-us/library/bb397926.aspx http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx http://dotnetslackers.com/articles/csharp/IntroducingLINQ1.aspx

31 | P a g i n a