. NET LINQ fra grunnen

Som programvareutviklere bruker vi mye tid på å utvinne og vise data fra mange forskjellige datakilder. Enten det er en XML-webservice av noe slag eller en fullverdig relasjonsdatabase, har vi blitt tvunget til å lære forskjellige metoder for datatilgang. Ville det ikke vært bra om tilgangsmetoden var den samme for alle datakilder? Vel, vi er heldige fordi, etter utgivelsen av C # 3.0 og .NET 3.5 Framework, har LINQ kommet for å forandre spillet for alltid.

Opplæringsdetaljer

  • Introduksjon til LINQ syntaks
  • Projeksjoner ved hjelp av LINQ
  • Raffinering av data
  • Standardoperatører

Oversikt over nåværende datatilgang

På .NET-plattformen har vi vært og fortsatt bruker ADO.NET
for tilgang til forskjellige datakilder. Open source-samfunnet har også gitt
utviklerne med en rekke alternativer.

Språkintegrert spørring er det nye tillegget til .NET
familie og som navnet antyder, er det den typen spørringsstil datatilgang som
støttes fullt ut av språket for effektivt å forene måten vi får tilgang til data på
og for å gjøre livet enklere. LINQ er i stand til å målrette mot en rekke forskjellige kilder, nemlig Oracle,
MSSQL, XML og noen andre, men for nå vil vi fokusere på de mest grunnleggende
alt, LINQ til objekter.

LINQ til objekter

Normalt, for å behandle og forbedre dataene i våre lister
og ulike andre datastrukturer, har vi brukt enten "foreach" loop eller en annen
type looping metode for å iterere gjennom objektene og behandle dem en etter
en i henhold til en viss tilstand. Dette er greit, men ærlig talt krever det mye
grunnleggende koding som vi alle ønsker at vi ikke måtte skrive. I hovedsak har vi hatt å fortelle
kompilere hver eneste detalj av prosessen for å manipulere dataene.

Dette er akkurat der LINQ skinner best. Hva LINQ tillater oss
å gjøre er å bare fortelle kompilatoren hva vi ønsker å utføre og la kompilatoren jobbe
ut den beste måten å faktisk oppnå det. Hvis du har brukt SQL-syntaks før, så er de enorme likhetene
mellom LINQ og eventuelle dialekter av SQL blir det første du vil legge merke til.
Som SQL støtter LINQ også "select", "from", "where", "join", "group by"
og "ordre av" søkeord. Her er et enkelt eksempel på å spørre en liste over objekter:

Listinitialisering:

 Liste ListOfCars = ny liste() nybil name = "Toyota", eier = "Alex", modell = 1992, ny bil name = "Mitsubishi", eier = "Jeff", modell = 2005, ny bil name = "Land Rover ", eier =" Danny ", modell = 2001, ny bil name =" BMW ", eier =" Danny ", modell = 2006, ny bil name =" Subaru ", eier =" Smith " = 2003;

Spørringen:

 IEnumerable QueryResult = fra bil i ListOfCars velg bil;

Den første delen av den forrige koden fyller bare en liste
med fire forekomster av "Bil" -klassen. Den neste delen av koden bruker imidlertid
"fra" og "velg" søkeord for å velge en gruppe objekter. Den største forskjellen
mellom SQL og LINQ er at "fra" søkeordet kommer før "velg"
søkeord fordi vi må først definere objektet vi vil operere på. Endelig
"select" -klausulen forteller kompilatoren hva vi ønsker å trekke ut i denne spørringen. Ovennevnte
kode utdrag bare alt som er på listen og tilordner det til "QueryResult"
variabel.

Når vi spør ting fra objekter (LINQ til objekter) vår
Spørsmål returnerer alltid en "IEnumrable"liste over objekter. I hovedsak den
"IEnumerable" type er den typen liste som avslører opptellingen, hvilken
støtter en enkel iterasjon over en ikke-generisk samling, og
er typen av hver oppføring i listen.
Ikke bekymre deg hvis du ikke er kjent med "enumerators" og "generics". Bare
Husk at resultatet av LINQ spørringer alltid er en samling som data
struktur som gjør det mulig å iterere gjennom det ved hjelp av en sløyfe som vist
under:

 foreach (bilbil i QueryResult) Console.WriteLine (bilnavn);

Vi lærte at LINQ alltid returnerer en samlingsstruktur tilsvarende
til andre lister. LINQ-spørringen utføres imidlertid ikke før resultatet er
åpnet av et annet stykke kode, som "foreach" -løkken ovenfor. Dette er til
la oss kontinuerlig definere søket uten overhead ved å revurdere
hvert nytt trinn i spørringen.

Anslag

Så langt så bra; men mesteparten av tiden vil våre spørsmål trenge
å være mer komplisert; så la oss prøve å projisere data. I SQL betyr Projection å velge
navnet på kolonnen (e) av tabell (er) som man ønsker å se vises i resultatet
av spørringen. I tilfelle av LINQ til objekter, vil utførelse av projeksjon resultere
i en annen spørresultatresultattype enn typen objekt som vi utfører
spørre på.

Det er to typer projeksjoner som vi kan gjøre. Vi kan
enten utføre en projeksjon basert på en eksisterende objekttype, eller gå helt
den andre veien ved å bruke anonyme typer. Følgende eksempel er det første
snill:

 IEnumerable QueryResult = fra bil i ListOfCars velg ny CarOwner owner_name = car.owner;

I forrige kode er typen av spørresultatet deklarert som
, som er forskjellig fra , typen som "ListOfCar" -variabelen er initialisert med. Vi har
brukte også det "nye" søkeordet og har gjort noen oppgaver inne i det krøllete
braketter. I ovennevnte kode, forteller "Select" med det "nye" søkeordet
kompilator for å opprette et nytt "CarOwner" -objekt for hver oppføring i spørringsresultatet.
Også ved å tildele verdier til den nye typen har vi initialisert hver forekomst
av 'CarOwner'-klassen.

Likevel, hvis du ikke allerede har en type definert til
bruk, kan du fremdeles utføre projeksjoner ved hjelp av anonyme typer.

Projeksjoner ved hjelp av anonyme typer

Det ville være et stort problem hvis du var for hver projeksjon
tvunget til å lage en ny type. Det er derfor, som av C # 3.0, støtte for Anonym
typer ble lagt til språket. En anonym type er erklært ved å bruke "var"
søkeord. Det forteller kompilatoren at typen av variabelen er ukjent til
den er tildelt for første gang.

 var QueryResult = fra bil i ListOfCars velg ny car_name = car.name, owner_name = car.owner; foreach (var entry i QueryResult) Console.WriteLine (entry.car_name);

Ovenstående er et eksempel på å utføre en spørring med Anonym
typer. Den eneste fangsten å se etter er at kompilatoren ikke vil
Tillat retur Anonymtyper fra metoder.

Å få tilgang til egenskapene til en anonym type er enkelt. I Visual Studio 2008, koden
Fullføring / Intellisense viser også egenskapene som er eksponert av den anonyme typen.

Raffinering av data

Vanligvis som en del av LINQ-spørringen, må vi også finjustere
spørringsresultat ved å spesifisere en tilstand. På samme måte som SQL, bruker LINQ også "hvor"
klausul for å fortelle kompilatoren hvilke forhold som er akseptable.

 IEnumerable QueryResult = fra bil i ListOfCars hvor car.name == "Subaru" velg bil;

Den forrige koden viser bruken av "hvor" klausulen og
tilstanden til å følge. For ytterligere å definere flere forhold, støtter LINQ
'og' (&& amp) og 'eller' (||) konstruksjonene. Den "hvor" delen av spørringen må alltid være a
Boolsk uttrykk, ellers vil kompilatoren klage.

Rekkefølge etter

Når du spør etter objekter, er det mulig å stole på spørringen
Målet er allerede sortert. Hvis ikke, kan LINQ ta seg av det
ved å bruke "ordre av" -klausulen som sikrer at resultatet av søket ditt er
ordentlig sortert.

 IEnumerable QueryResult = fra bil i ListOfCars orderby car.model velg bil;

Hvis du kjører koden ovenfor, ser du at resultatet av
spørringen er sortert i stigende rekkefølge. Du kan endre rekkefølgen ved å bruke "stigende" og "synkende"
søkeord, og videre endre rekkefølgen ved å angi mer enn ett felt å sortere
av. Følgende kode viser hvordan:

 IEnumerable QueryResult = fra bil i ListOfCars orderby car.model nedstigende velg bil;

gruppering

LINQ tillater også gruppering av spørringsresultatet med verdien av a
spesifikk egenskap som vist i dette eksemplet:

 var QueryResult = fra bil i ListOfCars gruppebil med bil. Eier i CarOwnersGroup velg CarOwnersGroup.Key;

Som du kan se, støtter LINQ "gruppe etter" -klausulen til
spesifiser hvilket objekt og hvilken eiendom du skal gruppere etter. Den "inn" søkeordet vil
så la oss prosjektet på et grupperesultat som kan nås med "nøkkelen"
eiendom.

tiltrer

LINQ støtter å koble data fra forskjellige samlinger til en
spørresultat. Du kan gjøre dette ved hjelp av "join" søkeordet for å spesifisere hvilke objekter
å bli med og bruke "på" søkeordet for å spesifisere det samsvarende forholdet mellom
de to objektene.

Initialiserende relatert liste:

 Liste ListOfCars = ny liste() ny bil name = "Mitsubishi", eier = "Jeff", modell = 2005, ny bil name = "Land Rover", eier = "Danny", modell = 2001, ny bil name = " Subaru ", eier =" Smith ", modell = 2003, ny bil name =" Toyota ", eier =" Alex ", modell = 1992, ny bil name =" BMW ", eier =" Danny ", modell = 2006,; Liste ListOfCarOwners = ny listeowner_name = "Danny", alder = 22, ny CarOwner owner_name = "Jeff", alder = 35, ny CarOwner owner_name = "Smith", alder = 19, ny CarOwner owner_name = "Alex", alder = 40;

Spørsmål:

 var QueryResult = fra bil i ListOfCars bli med på kjøretøy i ListOfCarOwners på car.owner lik carowner.owner_name velg ny name = car.name, owner = car.owner, owner_age = carowner.age;

I ovennevnte kode, ved hjelp av en anonym type, har vi blitt med
de to objektene i et enkelt spørresultat.

Objekthierarkier ved hjelp av gruppeledd

Så langt har vi lært hvordan vi kan bruke LINQ til å bygge en flat
liste spørresultat. Med LINQ er det også mulig å oppnå et hierarkisk spørsmål
Resultatet bruker "GroupJoin". I enkle ord kunne vi tildele objekter til
Egenskaper for hver oppføring med LINQ spørring.

 Liste ListOfCars = ny liste() ny bil name = "Mitsubishi", eier = "Jeff", modell = 2005, ny bil name = "Land Rover", eier = "Danny", modell = 2001, ny bil name = " Subaru ", eier =" Smith ", modell = 2003, ny bil name =" Toyota ", eier =" Alex ", modell = 1992, ny bil name =" BMW ", eier =" Danny ", modell = 2006,; Liste ListOfCarOwners = ny listeowner_name = "Danny", alder = 22, ny CarOwner owner_name = "Jeff", alder = 35, ny CarOwner owner_name = "Smith", alder = 19, ny CarOwner owner_name = "Alex", alder = 40; var QueryResult = fra kjelleren i ListOfCarOwners bli med på bil i ListOfCars på carowner.owner_name er lik car.owner til bilerGruppe velg ny name = carowner.owner_name, cars = carsGroup; Foreach (var caronner i QueryResult) foreach (var bil i carOwner.cars) Console.WriteLine ("Eiernavn: 0, bilnavn: 1, bilmodell: 2", carOwner.name, car.name , car.model);

I eksemplet ovenfor følger "Join" -klausulen en "inn i"
del. Dette er forskjellig fra den forrige deltidsoperasjonen vi så på. Her, "inn i"
Klausul brukes til å gruppere biler av eieren (i bilerGruppe) og tildele grupperingen til
"biler" eiendom av den anonyme typen.

Standard Query Operators

Hittil har alt som vi har sett blitt støttet av C # 3.0
syntaks. Det er imidlertid fortsatt et stort antall operasjoner som C # 3.0 ikke gjør
Brukerstøtte. Standard forespørselsoperatørene gir spørringsfunksjoner, inkludert
filtrering, projeksjon, aggregering, sortering og mer. Disse operasjonene støttes derfor
som metoder i LINQ biblioteket og kan utføres på grunn av en spørring som vist i
følgende skjermdump:

Disse operatørene er oppført nedenfor for din referanse.

Aggregate Operators

  • Sum: Returnerer summen av alle oppføringer
  • Max: returnerer oppføringen med den maksimale verdien
  • min: returnerer oppføringen med minimumsverdien
  • Gjennomsnitt: Returnerer gjennomsnittsverdien for samlingen
  • Aggregate: brukes til å lage en tilpasset aggregering
  • LongCount: Når du håndterer en stor samling, returnerer denne metoden en verdi opp til den største verdien støttet av den "lange" klassen
  • Telle: Returnerer et "heltall" for antall ting i samlingen

Element Operators

  • Først: returnerer første oppføring fra resultatinnsamlingen
  • FirstOrDefault: Hvis tom samling returnerer standardverdien, vil ellers returnere den første oppføringen fra samlingen
  • Enkelt: Returnerer kun element fra samlingen
  • SingleOrDefault: Hvis tom samling returnerer standardverdien, vil ellers bare returnere element fra samlingen
  • Siste: Returnerer den siste oppføringen fra samlingen
  • LastOrDefault: Hvis tom samling, returnerer standardverdien, ellers returnerer den siste oppføringen fra samlingen
  • ElementAt: returnerer elementet på den angitte posisjonen
  • ElementAtOrDefault: Hvis tom samling, returnerer standardverdien, ellers returnerer elementet på den angitte posisjonen

Angi tilhørende operatører

  • Unntatt: ligner på venstre tilkobling i SQL, returnerer oppføringer fra det ene settet som ikke finnes i et annet sett
  • Union: Returnerer alle oppføringer fra begge objektene
  • Krysse: Returnerer de samme elementene fra begge settene
  • Tydelig: returnerer unike oppføringer fra samlingen

Generasjonsoperatører

  • DefaultIfEmpty: Hvis resultatet er tomt returnerer standardverdien
  • Gjenta: gjentar på gjenværende gjenstander for spesifisert antall ganger
  • Tømme: Returnerer en tom IEnumerbar samling
  • Område: Returnerer en rekke tall for et spesifisert startnummer og teller

Raffinering Operatører

  • Hvor: vil returnere objekter som oppfyller den angitte tilstanden
  • OfType: vil returnere objekter av den angitte typen

Konverteringsoperatører

  • Å se opp: returnerer resultatet som et oppslag
  • Ramse opp: returnerer resultatet som en liste samling
  • ToDictionary: returnerer resultatet som en ordbok
  • ToArray: Returnerer resultatet som en Array-samling
  • AsQueryable: returnerer resultatet som en IQueryable
  • AsEnumerable: Returnerer resultatet som en IEnumerable
  • OfType: filtrerer samlingen i henhold til spesifisert type
  • Cast: brukes til å konvertere en svakt skrevet samling til en sterkt skrevet samling

Partisjoneringsoperatører

  • Ta: Returnerer et spesifisert antall poster
  • Takewhile: Returnerer et spesifisert antall poster mens den angitte tilstanden vurderes til sann
  • Hopp: hopper over angitt antall oppføringer og returnerer resten
  • SkipWhile: hopper over angitt antall oppføringer mens den angitte tilstanden vurderes til ekte

Kvantitetsoperatører

  • Noen: returnerer true eller false for en spesifisert tilstand
  • inneholder: returnerer true eller false for eksistensen av det angitte objektet
  • Alle: returnerer sant eller falskt til alle objekter som oppfyller den angitte tilstanden

Bli med operatører

  • Bli med: returnerer oppføringer der nøklene i settene er de samme
  • GroupJoin: brukes til å bygge hierarkiske objekter basert på et mester- og detaljforhold

Likestillingsoperatører

  • SequenceEqual: returnerer sant når samlinger er like

Sortering Operatører

  • Omvendt: returnerer en reversert samling
  • ThenBy: brukes til å utføre videre sortering
  • ThenByDescending: brukes til å utføre videre sortering i synkende rekkefølge
  • Rekkefølge etter: brukes til å definere rekkefølge
  • OrderByDescending: brukes til å definere synkende rekkefølge

Projeksjonsoperatører

  • SelectMany: brukes til å flate en hierarkisk samling
  • Å velge: brukes til å identifisere egenskapene for å returnere

Sammenkoblingsoperatører

  • concat: brukes til å sammenkoble to samlinger

Så hva nå?

LINQ har vist seg å være veldig nyttig for å spørre objekter, og den SQL-lignende syntaksen gjør det enkelt å
lær og bruk. Det store antallet standardoperatører gjør det også mulig å kutte en rekke operatører
å utføre komplekse spørsmål. I en oppfølging av denne opplæringen vurderer vi hvordan LINQ kan brukes til
spørringsdatabaser og XML-innhold ...

Selg .NET-skript og komponenter på CodeCanyon



  • Følg oss på Twitter, eller abonner på Nettuts + RSS-feed for de beste webutviklingsopplæringene på nettet.