.NET LINQ de la Scratch

În calitate de dezvoltatori de software, petrecem mult timp extragând și afișând date din mai multe surse de date diferite. Fie că este vorba de un serviciu de web XML sau de o bază de date relațională, am fost forțați să învățăm diferite metode de acces la date. Nu ar fi minunat dacă metoda de acces a fost aceeași pentru toate sursele de date? Ei bine, avem noroc deoarece, de la lansarea lui C # 3.0 si a .NET 3.5 Framework, LINQ a venit sa schimbe jocul pentru totdeauna.

Detalii tutoriale

  • Introducere în sintaxa LINQ
  • Proiecții utilizând LINQ
  • Rafinarea datelor
  • Operatori standard

Prezentarea generală a accesului curent

Pe platforma .NET am fost și încă mai folosim ADO.NET
pentru a accesa diferite surse de date. Comunitatea open source a oferit de asemenea
dezvoltatorii cu o serie de alternative.

Interogarea integrată a limbii este noua adăugire în .NET
familia și, după cum sugerează numele, este tipul de interogare a stilului de interogare care
este pe deplin susținut de limbă pentru a uni efectiv modul în care accesăm datele
și pentru a ne ușura viața. LINQ este capabil să vizeze o serie de surse diferite, și anume Oracle,
MSSQL, XML și câteva altele, dar pentru moment ne vom concentra pe cele mai de bază
toate, LINQ către obiecte.

LINQ către obiecte

În mod normal, pentru a procesa și rafina datele din listele noastre
și alte structuri de date, am folosit fie bucla "foreach", fie alta
tip de metoda looping pentru a itera prin obiecte si proceseaza-le una prin
unul conform unor condiții. Acest lucru este bine, dar sincer necesită multe
codificare de bază pe care noi toți dorim că nu trebuie să o scriem. În esență, trebuia să le spunem
compilează fiecare detaliu al procesului pentru a manipula datele.

Acesta este exact locul în care LINQ strălucește cel mai bine. Ce ne permite LINQ
este de a spune pur și simplu compilatorului ceea ce dorim să realizăm și să lăsăm compilatorul să lucreze
cel mai bun mod de a realiza acest lucru. Dacă ați folosit deja sintaxa SQL, asemănările masive
între LINQ și orice dialecte de SQL va fi primul lucru pe care îl veți observa.
La fel ca SQL, LINQ suportă și "selectați", "de la", "unde", "alăturați", "grupați prin"
și "ordonează după" cuvintele cheie. Iată un exemplu simplu de interogare a unei liste de obiecte:

Inițializare listă:

 Listă ListOfCars = Listă nouă(noul Masina name = "Toyota", proprietar = "Alex", model = 1992), noul Masina name = "Land" Rover ", proprietar =" Danny ", model = 2001, noul Car name =" BMW ", proprietar =" Danny ", model = 2006) = 2003;

Interogarea:

 IEnumerable QueryResult = din masina selectata in cartea ListOfCars;

Prima parte a codului anterior ocupă o listă
cu patru exemple din clasa "Mașină". Următoarea parte a codului, cu toate acestea, utilizează
cuvinte cheie "de la" și "selectați" pentru a selecta un grup de obiecte. Principala diferență
între SQL și LINQ este că cuvântul cheie "de la" vine înainte de "selectați"
pentru că trebuie mai întâi să definim obiectul pe care dorim să lucrăm. In cele din urma
clauza "select" spune compilatorului ceea ce dorim să extragem în această interogare. De mai sus
codul extrage tot ceea ce este în listă și îl atribuie "QueryResult"
variabil.

Atunci când interogăm lucrurile de la obiecte (LINQ la obiecte)
interogările întotdeauna întorc un "IEnumrable"lista de obiecte
Tipul "IEnumerable" este tipul de listă care expune enumeratorul, care
sprijină o simplă iterație asupra unei colecții non-generice și
este tipul fiecărei intrări din listă.
Nu vă faceți griji dacă nu sunteți familiarizați cu "enumeratorii" și "generica". Doar
amintiți-vă că rezultatul interogărilor LINQ este întotdeauna o colecție ca datele
structură care permite iterarea prin ea folosind o buclă așa cum este arătată
muget:

 foreach (Mașină în QueryResult) Console.WriteLine (car.name);

Am aflat că LINQ întoarce întotdeauna o structură de colectare similară
la alte liste. Cu toate acestea, interogarea LINQ nu se execută până când rezultatul nu este
accesat de o altă bucată de cod, precum bucla "foreach" de mai sus. Asta este
ne permite să definim în mod continuu interogarea fără cheltuieli generale prin reevaluare
fiecare pas nou în interogare.

proiecţiile

Până acum, bine; dar de cele mai multe ori întrebările noastre vor fi necesare
să fie mai complexă; așa că să încercăm să proiectăm date. În SQL, proiecția înseamnă selectarea
numele coloanelor din tabelul (tabelele) pe care doriți să le vedeți în rezultat
din interogare. În cazul LINQ către obiecte, se va realiza Proiectarea
într-un alt tip de rezultat de interogare decât tipul de obiect pe care îl executăm
interogare pe.

Există două tipuri de Proiecții pe care le putem face. Noi putem
fie efectuați o Proiectare bazată pe un tip de obiect existent, fie mergeți complet
invers, folosind tipuri anonime. Exemplul de mai jos este primul
drăguț:

 IEnumerable QueryResult = din mașină în ListOfCars selectați noul CarOwner owner_name = proprietar de mașină;

În codul precedent, tipul de rezultat al interogării este declarat ca
, care este diferit de , tipul care este inițializat cu variabila "ListOfCar". Noi avem
au folosit de asemenea cuvântul cheie "nou" și au făcut unele sarcini în interiorul buclatului
între paranteze. În codul de mai sus, folosirea "selectați" cu cuvântul cheie "nou" indică
compilator pentru a instanțializa un nou obiect "CarOwner" pentru fiecare intrare din rezultatul interogării.
De asemenea, prin atribuirea de valori noului tip, am inițializat fiecare instanță
din clasa "CarOwner".

Cu toate acestea, dacă nu aveți deja un tip definit
utilizați, puteți efectua în continuare proiecții utilizând tipuri anonime.

Proiecții care utilizează tipuri anonime

Ar fi o problemă mare dacă, pentru fiecare Proiectare, ați fost
forțat să creeze un tip nou. De aceea, din C # 3.0, suport pentru Anonymous
au fost adăugate tipuri în limba respectivă. Un tip anonim este declarat folosind "var"
cuvinte cheie. Spune compilatorului că tipul de variabilă este necunoscut până la
este atribuită pentru prima dată.

 var QueryResult = din mașină în ListOfCars selectați noi car_name = nume_carton, nume_proprietar = proprietar auto; foreach (intrare var în QueryResult) Console.WriteLine (entry.car_name);

Cele de mai sus reprezintă un exemplu de efectuare a unei interogări cu Anonim
tipuri. Singura captura pe care trebuie să o privești este că compilatorul nu o va face
permite returnarea tipurilor anonime din metode.

Accesul la proprietățile unui tip anonim este ușor. În Visual Studio 2008, codul
Completarea / Intellisense enumeră, de asemenea, proprietățile expuse de tipul Anonim.

Rafinarea datelor

De obicei, ca parte a interogării LINQ, trebuie, de asemenea, să îmbunătățim
interogare prin specificarea unei condiții. La fel ca SQL, LINQ utilizează prea "unde"
clauza de a spune compilatorului ce condiții sunt acceptabile.

 IEnumerable QueryResult = din mașină în ListOfCars unde car.name == "Subaru" selectați mașina;

Codul precedent demonstrează utilizarea clauzelor "unde" și
condiția de urmat. Pentru a defini mai multe condiții, LINQ acceptă
"și" (&& amp) și "sau" (||) constructe. Partea "unde" din interogare trebuie să fie întotdeauna a
Expresia booleană, altfel compilatorul se va plânge.

Ordonează prin

Când interogați obiecte, este posibil să se bazeze pe interogare
țintă fiind deja sortată. Dacă nu este cazul, LINQ poate avea grijă de asta
prin folosirea clauzei "order by" care va asigura rezultatul interogării dumneavoastră
ordonată corect.

 IEnumerable QueryResult = din masina in ListOfCars orderby car.model select auto;

Dacă executați codul de mai sus, veți vedea că rezultatul
interogarea este sortată în ordine ascendentă. Puteți să modificați ordinea utilizând "ascendent" și "descendent"
cuvinte cheie și modificați în continuare ordinea, specificând mai multe câmpuri de sortare
de. Următorul cod arată cum:

 IEnumerable QueryResult = de la masina in ListOfCars comandaby car.model descrescator selectare masina;

Gruparea

LINQ permite, de asemenea, gruparea rezultatului interogării cu valoarea a
specifică, așa cum se arată în acest exemplu:

 var QueryResult = de la masina in grupul ListOfCars masina de catre proprietarul masinii in carOwnersGroup select carOwnersGroup.Key;

După cum puteți vedea, LINQ acceptă clauza "grup de către" la
specificați ce obiect și de ce proprietate să grupați prin. Cuvântul cheie "în" va fi
apoi permiteți-ne să proiectăm un rezultat de grup care poate fi accesat de către "cheie"
proprietate.

se alătură

LINQ acceptă unificarea datelor dintr-o colecție diferită
rezultatul interogării. Puteți face acest lucru folosind cuvântul cheie "join" pentru a specifica ce obiecte
să se alăture și să utilizeze cuvântul cheie "on" pentru a specifica relația de potrivire dintre
cele două obiecte.

Inițializarea listei asociate:

 Listă ListOfCars = Listă nouă(noul Masina name = "Mitsubishi", proprietar = "Jeff", model = 2005), noul Masina name = " Subaru ", proprietar =" Smith ", model = 2003, noul Masina name =" Toyota ", proprietar =" Alex ", model = 1992) = 2006,; Listă ListOfCarOwners = Listă nouă() noul CarOwner owner_name = "Danny", vârsta = 22), noul CarOwner owner_name = "Jeff", vârsta = 35 "Alex", vârsta = 40;

Solicitare:

 var QueryResult = de la masina in ListOfCars se alatura proprietarului in ListOfCarOwners pe car.owner este egal cu carowner.owner_name selectati noi name = car.name, owner = car.owner, owner_age = carowner.age;

În codul de mai sus, folosind un tip Anonim, ne-am alăturat
cele două obiecte într-un singur rezultat al interogării.

Ierarhiile de obiecte utilizând Grupul de asociere

Până acum, am învățat cum putem folosi LINQ pentru a construi un apartament
afișați rezultatul interogării. Cu LINQ, este posibilă și o interogare ierarhică
rezultat folosind "GroupJoin". Cu simple cuvinte, am putea atribui obiecte
proprietățile fiecărei intrări cu interogare LINQ.

 Listă ListOfCars = Listă nouă(noul Masina name = "Mitsubishi", proprietar = "Jeff", model = 2005), noul Masina name = " Subaru ", proprietar =" Smith ", model = 2003, noul Masina name =" Toyota ", proprietar =" Alex ", model = 1992) = 2006,; Listă ListOfCarOwners = Listă nouă() noul CarOwner owner_name = "Danny", vârsta = 22), noul CarOwner owner_name = "Jeff", vârsta = 35 "Alex", vârsta = 40; var QueryResult = de la proprietar de mașini în ListOfCarOwners se alăture mașinii în ListOfCars pe carowner.owner_name este egal cu car.owner în carsGroup selectați noi name = carowner.owner_name, cars = carsGroup; (nume de proprietar: 0, numele masinii: 1, modelul masinii: 2 ", carOwner.name, car.name (preludiul auto in cartierul QueryResult) , model de mașină);

În exemplul de mai sus, clauza "Alăturați-vă" este urmată de o rubrică "în"
parte. Acest lucru diferă de funcționarea precedentă în care ne-am uitat. Aici, "în"
clauza este folosită pentru a grupa autoturismele de către proprietar (în grupuri de autoturisme) și a aloca gruparea la
"autoturisme" de tip anonim.

Operatori de interogare standard

Până acum, tot ceea ce am văzut a fost susținut de C # 3.0
sintaxă. Cu toate acestea, există încă un număr mare de operații pe care C # 3.0 nu le utilizează
a sustine. Operatorii standard de interogare includ capabilități de interogare, inclusiv
filtrarea, proiecția, agregarea, sortarea și multe altele. Prin urmare, aceste operațiuni sunt susținute
ca metodă a bibliotecii LINQ și pot fi executate pe baza rezultatelor unei interogări ca cea prezentată în
următorul ecran:

Acești operatori sunt listați mai jos pentru referință.

Operatori agregați

  • Sumă: returnează suma tuturor intrărilor
  • Max: returnează intrarea cu valoarea maximă
  • min: returnează intrarea cu valoarea minimă
  • In medie: returnează valoarea medie pentru colecție
  • Agregat: utilizat pentru crearea unei agregări personalizate
  • LongCount: atunci când se ocupă de o colecție mare, această metodă va returna o valoare până la cea mai mare valoare susținută de clasa "lungă"
  • Numara: returnează un "număr întreg" pentru numărul de articole din colecție

Elemente Operatori

  • Primul: returnează prima intrare din colecția de rezultate
  • FirstOrDefault: dacă colecția goală va returna valoarea implicită, în caz contrar se va returna prima intrare din colecție
  • Singur: va returna numai elementul din colecție
  • SingleOrDefault: dacă colecția goală va returna valoarea implicită, în caz contrar se va returna numai elementul din colecție
  • Ultimul: returnează ultima intrare din colecție
  • LastOrDefault: dacă colecția goală va returna valoarea implicită, în caz contrar returnează ultima intrare din colecție
  • ElementAt: returnează elementul la poziția specificată
  • ElementAtOrDefault: dacă colecția goală va returna valoarea implicită, în caz contrar returnează elementul la poziția specificată

Setați operatori apropiați

  • Cu exceptia: similar cu intrarea din stânga în SQL, va returna intrările dintr-un set care nu există într-un alt set
  • Uniune: returnează toate intrările de la ambele obiecte
  • intersecta: returnează aceleași elemente din cele două seturi
  • Distinct: returnează intrări unice din colecție

Operatori de generare

  • DefaultIfEmpty: dacă rezultatul este gol, returnează valoarea implicită
  • Repeta: se repetă la revenirea obiectelor de câte ori se specifică
  • Gol: va returna o colecție goală numită IEnumerable
  • Gamă: returnează o serie de numere pentru un număr de început specificat și numărare

Operatori de rafinare

  • Unde: va returna obiecte care îndeplinesc condiția specificată
  • OfType: va returna obiecte de tipul specificat

Operatorii de conversie

  • A căuta: returnează rezultatul ca o căutare
  • A lista: returnează rezultatul ca o colecție de liste
  • ToDictionary: returnează rezultatul ca dicționar
  • ToArray: returnează rezultatul ca colecție Array
  • AsQueryable: returnează rezultatul ca un IQueryable
  • AsEnumerable: returnează rezultatul ca un IEnumerabil
  • OfType: filtrează colecția în funcție de tipul specificat
  • arunca: folosit pentru a transforma o colecție slab tastat într-o colecție puternic tastat

Operatori de partiționare

  • Lua: returnează un anumit număr de înregistrări
  • Takewhile: returnează un anumit număr de înregistrări în timp ce condiția specificată este evaluată la adevărată
  • Ocolire: sări peste numărul specificat de intrări și returnează restul
  • SkipWhile: sări peste numărul de intrări specificate, în timp ce condiția specificată este evaluată la adevărată

Operatori de cuantigatori

  • Orice: returnează true sau false pentru o condiție specificată
  • Conține: returnează adevărat sau fals pentru existența obiectului specificat
  • Toate: returnează true sau false toate obiectele care îndeplinesc condiția specificată

Alăturați-vă operatorilor

  • A adera: returnează intrările în care tastele din seturi sunt aceleași
  • GroupJoin: utilizat pentru a construi obiecte ierarhice bazate pe o relație master și detaliu

Egalitatea operatorilor

  • SequenceEqual: returnează adevărat atunci când colecțiile sunt egale

Sortarea operatorilor

  • Inversa: returnează o colecție inversată
  • Apoi prin: utilizat pentru a efectua o sortare suplimentară
  • ThenByDescending: utilizate pentru a efectua o sortare suplimentară în ordine descrescătoare
  • orderby: utilizat pentru a defini ordinea
  • OrderByDescending: utilizat pentru a defini ordinea descrescătoare

Proiectoare

  • SelectMany: folosit pentru a aplatiza o colecție ierarhică
  • Selectați: utilizat pentru a identifica proprietățile care trebuie returnate

Operatori de concatenare

  • concat: utilizat pentru a concatena două colecții

Deci, ce acum?

LINQ sa dovedit a fi foarte util pentru interogarea obiectelor, iar sintaxa asemănătoare SQL o face ușor
să învețe și să folosească. De asemenea, numărul mare de operatori standard face posibilă alianța unui număr de operatori
pentru a efectua interogări complexe. Într-o continuare a acestui tutorial, vom examina modul în care poate fi folosit LINQ
interogări baze de date și conținut XML ...

Vindem Scripturi .NET și componente pe CodeCanyon



  • Urmați-ne pe Twitter sau abonați la Nettuts + RSS Feed pentru cele mai bune tutoriale de dezvoltare web de pe web.
Cod