LINQ .NET da zero

Come sviluppatori di software, dedichiamo molto tempo all'estrazione e alla visualizzazione di dati da diverse fonti di dati. Che si tratti di un servizio Web XML di qualche tipo o di un database relazionale completo, siamo stati costretti ad apprendere diversi metodi di accesso ai dati. Non sarebbe bello se il metodo di accesso fosse lo stesso per tutte le fonti di dati? Bene, siamo fortunati perché, a partire dal rilascio di C # 3.0 e .NET 3.5 Framework, LINQ è venuto per cambiare il gioco per sempre.

Dettagli dell'esercitazione

  • Introduzione alla sintassi LINQ
  • Proiezioni usando LINQ
  • Raffinazione dei dati
  • Operatori standard

Panoramica sull'accesso ai dati corrente

Sulla piattaforma .NET siamo stati e stiamo ancora utilizzando ADO.NET
per accedere a diverse fonti di dati. La comunità open source ha anche fornito
gli sviluppatori con un numero di alternative.

Language Integrated Query è la nuova aggiunta a .NET
famiglia e come suggerisce il nome è il tipo di accesso ai dati di stile di query che
è completamente supportato dalla lingua per unificare efficacemente il modo in cui accediamo ai dati
e per rendere più facile la nostra vita. LINQ è in grado di indirizzare un numero di fonti diverse, vale a dire Oracle,
MSSQL, XML e pochi altri, ma per ora ci concentreremo sui più basilari di
tutto, LINQ agli oggetti.

LINQ agli oggetti

Normalmente, per elaborare e perfezionare i dati all'interno dei nostri elenchi
e varie altre strutture dati, abbiamo usato il ciclo 'foreach' o un altro
tipo di metodo di looping per iterare attraverso gli oggetti ed elaborarli uno per
uno secondo alcune condizioni. Questo va bene, ma francamente richiede molto
codifica di base che tutti desideriamo non dover scrivere. In sostanza, abbiamo dovuto dire al
compilatore ogni singolo dettaglio del processo al fine di manipolare i dati.

Questo è esattamente il punto in cui LINQ risplende meglio. Cosa LINQ ci consente
fare è semplicemente dire al compilatore cosa ci piacerebbe eseguire e lasciare che il compilatore funzioni
il modo migliore per realizzarlo. Se hai già usato la sintassi SQL, le somiglianze massicce
tra LINQ e qualsiasi dialetto di SQL sarà la prima cosa che noterai.
Come SQL, anche LINQ supporta "select", "from", "where", "join", "group by"
e "ordina per" parole chiave. Ecco un semplice esempio di interrogare un elenco di oggetti:

Inizializzazione dell'elenco:

 Elenco ListOfCars = nuova lista() new Car name = "Toyota", owner = "Alex", model = 1992, nuova Car name = "Mitsubishi", owner = "Jeff", model = 2005, new Car name = "Land Rover ", owner =" Danny ", model = 2001, nuova Car name =" BMW ", owner =" Danny ", model = 2006, nuova Car name =" Subaru ", owner =" Smith ", modello = 2003;

La query:

 IEnumerable QueryResult = dalla macchina in ListOfCars seleziona auto;

La prima parte del codice precedente popola semplicemente una lista
con quattro esempi della classe 'Car'. La parte successiva del codice, tuttavia, utilizza il
"da" e "seleziona" parole chiave per selezionare un gruppo di oggetti. La differenza principale
tra SQL e LINQ è che la parola chiave "da" viene prima della "selezione"
parola chiave perché dobbiamo prima definire l'oggetto su cui vogliamo operare. Finalmente
la clausola "select" dice al compilatore cosa vogliamo estrarre in questa query. Quanto sopra
codice estrae semplicemente tutto ciò che è nella lista e lo assegna al "QueryResult"
variabile.

Quando interrogiamo le cose dagli oggetti (LINQ agli oggetti) nostri
le query restituiscono sempre un "IEnumrable""elenco di oggetti. Essenzialmente il
Il tipo "IEnumerable" è il tipo di elenco che espone l'enumeratore, che
supporta una semplice iterazione su una raccolta non generica, e
è il tipo di ciascuna voce nell'elenco.
Non preoccuparti se non hai familiarità con "enumeratori" e "generici". Appena
ricorda che il risultato delle query LINQ è sempre una raccolta come i dati
struttura che consente di scorrere attraverso di esso utilizzando un ciclo come mostrato
sotto:

 foreach (Car car in QueryResult) Console.WriteLine (car.name);

Abbiamo appreso che LINQ restituisce sempre una struttura di raccolta simile
a qualsiasi altra lista. Tuttavia, la query LINQ non viene eseguita finché non si verifica il risultato
accesso da qualche altro pezzo di codice, come il ciclo "foreach" sopra. Questo è per
consentirci di definire continuamente la query senza il sovraccarico mediante una nuova valutazione
ogni nuovo passo nella query.

proiezioni

Fin qui tutto bene; ma la maggior parte delle volte, le nostre domande avranno bisogno
essere più complesso; quindi proviamo a proiettare i dati. In SQL, Proiezione significa selezionare
il nome della (e) colonna (e) della (e) tabella (e) che si desidera vedere apparire nel risultato
della query. Nel caso di LINQ to Objects, si verificherà l'esecuzione della proiezione
in un tipo di risultato di una query diversa dal tipo di oggetto che eseguiamo
interrogare su.

Esistono due tipi di Proiezioni che possiamo fare. Noi possiamo
eseguire una proiezione basata su un tipo di oggetto esistente o andare completamente
l'altro modo usando tipi anonimi. Il seguente esempio è del primo
genere:

 IEnumerable QueryResult = dalla macchina in ListOfCars seleziona il nuovo CarOwner owner_name = car.owner;

Nel codice precedente, il tipo del risultato della query è dichiarato come
, che è diverso da , il tipo con cui viene inizializzata la variabile 'ListOfCar' con. abbiamo
ha anche usato la parola chiave "nuova" e ha eseguito alcuni compiti all'interno del riccio
parentesi. Nel codice sopra, usando "seleziona" con la parola chiave "nuova" si dice il
compilatore per istanziare un nuovo oggetto 'CarOwner' per ogni voce nel risultato della query.
Inoltre, assegnando valori al nuovo tipo, abbiamo inizializzato ogni istanza
della classe 'CarOwner'.

Tuttavia, se non si dispone già di un tipo definito
utilizzare, è ancora possibile eseguire proiezioni utilizzando tipi anonimi.

Proiezioni usando tipi anonimi

Sarebbe una grande seccatura se tu fossi per ogni proiezione
costretto a creare un nuovo tipo. Ecco perché, a partire da C # 3.0, il supporto per Anonymous
i tipi sono stati aggiunti alla lingua. Un tipo anonimo è dichiarato usando la "var"
parola chiave. Indica al compilatore che il tipo della variabile è sconosciuto fino al
è assegnato per la prima volta.

 var QueryResult = dalla macchina in ListOfCars seleziona new car_name = car.name, owner_name = car.owner; foreach (var entry in QueryResult) Console.WriteLine (entry.car_name);

Quanto sopra è un esempio di esecuzione di una query con Anonymous
tipi. L'unico problema da considerare è che il compilatore no
consentire la restituzione dei tipi anonimi dai metodi.

L'accesso alle proprietà di un tipo Anonimo è facile. In Visual Studio 2008, il codice
Completamento / Intellisense elenca anche le proprietà esposte dal tipo Anonimo.

Raffinazione dei dati

Solitamente come parte della query LINQ, dobbiamo anche perfezionare il
risultato della query specificando una condizione. Proprio come SQL, anche LINQ usa il "dove"
clausola per dire al compilatore quali condizioni sono accettabili.

 IEnumerable QueryResult = dalla macchina in ListOfCars dove car.name == "Subaru" seleziona la macchina;

Il codice precedente dimostra l'uso della clausola "where" e
la condizione da seguire. Per definire ulteriormente condizioni multiple, LINQ supporta
i costrutti 'and' (&& amp) e 'or' (||). La parte "where" della query deve sempre essere a
Espressione booleana, altrimenti il ​​compilatore si lamenterà.

Ordinato da

Quando si interrogano oggetti, è possibile fare affidamento sulla query
obiettivo già in ordine. In caso contrario, LINQ può occuparsene
utilizzando la clausola "order by" che garantirà il risultato della tua query
correttamente ordinato.

 IEnumerable QueryResult = dalla macchina in ListOfCars orderby car.model seleziona car;

Se esegui il codice sopra, vedrai che il risultato del
la query è ordinata in ordine crescente. Puoi modificare l'ordine usando "ascendente" e "discendente"
parole chiave, e modificare ulteriormente l'ordine specificando più di un campo da ordinare
di. Il codice seguente mostra come:

 IEnumerable QueryResult = dalla macchina in ListOfCars orderby car.model discendente select car;

Raggruppamento

LINQ consente inoltre di raggruppare il risultato della query in base al valore di a
proprietà specifiche come mostrato in questo esempio:

 var QueryResult = dall'auto in ListOfCars gruppo auto da car.owner in carOwnersGroup seleziona carOwnersGroup.Key;

Come puoi vedere, LINQ supporta la clausola "group by" in
specificare quale oggetto e in base a quale proprietà raggruppare. La parola chiave "in" sarà
quindi permettici di proiettare su un risultato di raggruppamento a cui si può accedere tramite la "Chiave"
proprietà.

Si unisce

LINQ supporta l'unione di dati da raccolte diverse in uno solo
risultato della query. Puoi farlo usando la parola chiave "join" per specificare quali oggetti
per unire e utilizzare la parola chiave "on" per specificare la relazione di corrispondenza tra
i due oggetti.

Inizializzazione dell'elenco correlato:

 Elenco ListOfCars = nuova lista() new Car name = "Mitsubishi", owner = "Jeff", model = 2005, nuova Car name = "Land Rover", owner = "Danny", model = 2001, new Car name = " Subaru ", owner =" Smith ", model = 2003, nuova Car name =" Toyota ", owner =" Alex ", model = 1992, nuova Car name =" BMW ", owner =" Danny ", modello = 2006,; Elenco ListOfCarOwners = new List() new CarOwner owner_name = "Danny", age = 22, nuovo CarOwner owner_name = "Jeff", età = 35, nuovo CarOwner owner_name = "Smith", age = 19, nuovo CarOwner owner_name = "Alex", età = 40 anni;

Query:

 var QueryResult = dalla macchina in ListOfCars unisciti al proprietario di una proprietà in ListOfCarOwners su car.owner equivale a carowner.owner_name seleziona new name = car.name, owner = car.owner, owner_age = carowner.age;

Nel codice sopra, usando un tipo Anonimo, ci siamo uniti
i due oggetti in un risultato di una singola query.

Gerarchie oggetto che utilizzano i join di gruppo

Finora, abbiamo imparato come possiamo usare LINQ per costruire un appartamento
elenca il risultato della query. Con LINQ, è anche possibile ottenere una query gerarchica
risultato utilizzando "GroupJoin". In parole semplici, potremmo assegnare oggetti a
proprietà di ogni voce con query LINQ.

 Elenco ListOfCars = nuova lista() new Car name = "Mitsubishi", owner = "Jeff", model = 2005, nuova Car name = "Land Rover", owner = "Danny", model = 2001, new Car name = " Subaru ", owner =" Smith ", model = 2003, nuova Car name =" Toyota ", owner =" Alex ", model = 1992, nuova Car name =" BMW ", owner =" Danny ", modello = 2006,; Elenco ListOfCarOwners = new List() new CarOwner owner_name = "Danny", age = 22, nuovo CarOwner owner_name = "Jeff", età = 35, nuovo CarOwner owner_name = "Smith", age = 19, nuovo CarOwner owner_name = "Alex", età = 40 anni; var QueryResult = dal proprietario di una macchina in ListOfCarOwners unire l'auto in ListOfCars su carowner.owner_name è uguale a car.owner in carsGroup seleziona new name = carowner.owner_name, cars = carsGroup; foreach (var carOwner in QueryResult) foreach (var car in carOwner.cars) Console.WriteLine ("Nome proprietario: 0, nome auto: 1, modello di auto: 2", carOwner.name, car.name , modello d'auto);

Nell'esempio sopra, la clausola "Join" è seguita da un "in"
parte. Ciò differisce dall'operazione di join precedente che abbiamo esaminato. Qui, il "dentro"
la clausola viene utilizzata per raggruppare le auto dal proprietario (in carsGroup) e assegnare il raggruppamento al
proprietà "auto" del tipo anonimo.

Operatori di query standard

Finora, tutto ciò che abbiamo visto è stato supportato dal C # 3.0
sintassi. Tuttavia, c'è ancora un gran numero di operazioni che C # 3.0 non ha
supporto. Gli operatori di query standard forniscono funzionalità di query tra cui
filtraggio, proiezione, aggregazione, ordinamento e altro. Queste operazioni sono quindi supportate
come metodi della libreria LINQ e può essere eseguito al risultato di una query come mostrato in
seguente schermata:

Questi operatori sono elencati di seguito come riferimento.

Operatori aggregati

  • Somma: restituisce la somma di tutte le voci
  • Max: restituisce la voce con il valore massimo
  • min: restituisce la voce con il valore minimo
  • Media: restituisce il valore medio per la raccolta
  • Aggregato: utilizzato per creare un'aggregazione personalizzata
  • LongCount: quando si ha a che fare con una grande collezione, questo metodo restituirà un valore fino al valore più grande supportato dalla classe "long"
  • Contare: restituisce un "intero" per il conteggio degli elementi nella raccolta

Operatori di elementi

  • Primo: restituisce la prima voce dalla raccolta dei risultati
  • FirstOrDefault: se raccolta vuota, restituirà il valore predefinito, altrimenti restituirà la prima voce dalla raccolta
  • singolo: restituirà solo l'elemento dalla raccolta
  • SingleOrDefault: se raccolta vuota, restituirà il valore predefinito, altrimenti restituirà solo l'elemento dalla raccolta
  • Scorso: restituisce l'ultima voce dalla raccolta
  • LastOrDefault: se raccolta vuota, restituirà il valore predefinito, altrimenti restituisce l'ultima voce dalla raccolta
  • ElementAt: restituisce l'elemento nella posizione specificata
  • ElementAtOrDefault: se raccolta vuota, restituirà il valore predefinito, altrimenti restituisce l'elemento nella posizione specificata

Imposta operatori correlati

  • tranne: simile al join sinistro in SQL, restituirà le voci da un set che non esiste in un altro set
  • Unione: restituisce tutte le voci da entrambi gli oggetti
  • intersecare: restituisce gli stessi elementi da entrambi i gruppi
  • distinto: restituisce voci univoche dalla raccolta

Operatori di generazione

  • DefaultIfEmpty: se il risultato è vuoto, restituisce il valore predefinito
  • Ripetere: si ripete su oggetti di ritorno per un numero specificato di volte
  • Vuoto: restituirà una raccolta IEnumerable vuota
  • Gamma: restituisce un intervallo di numeri per un numero iniziale e un conteggio specificati

Raffinazione Operatori

  • Dove: restituirà oggetti che soddisfano la condizione specificata
  • OfType: restituirà oggetti del tipo specificato

Operatori di conversione

  • ToLookup: restituisce il risultato come una ricerca
  • Elencare: restituisce il risultato come una raccolta di elenchi
  • ToDictionary: restituisce il risultato come dizionario
  • ToArray: restituisce il risultato come raccolta di Array
  • AsQueryable: restituisce il risultato come IQueryable
  • AsEnumerable: restituisce il risultato come IEnumerable
  • OfType: filtra la collezione in base al tipo specificato
  • lanciare: utilizzato per convertire una raccolta debolmente tipizzata in una raccolta fortemente tipizzata

Operatori di partizionamento

  • Prendere: restituisce un numero specificato di record
  • TakeWhile: restituisce un numero specificato di record mentre la condizione specificata restituisce true
  • Salta: salta il numero specificato di voci e restituisce il resto
  • SkipWhile: ignora il numero specificato di voci mentre la condizione specificata viene valutata su true

Operatori di quantificatori

  • Qualunque: restituisce true o false per una condizione specificata
  • contiene: restituisce true o false per l'esistenza dell'oggetto specificato
  • Tutti: restituisce true o false a tutti gli oggetti che soddisfano la condizione specificata

Unisciti agli operatori

  • Aderire: restituisce le voci in cui le chiavi nei set sono uguali
  • GroupJoin: utilizzato per creare oggetti gerarchici in base a una relazione principale e dettagliata

Operatori di uguaglianza

  • SequenceEqual: restituisce true quando le raccolte sono uguali

Operatori di ordinamento

  • Inverso: restituisce una raccolta inversa
  • ThenBy: utilizzato per eseguire ulteriori ordinamenti
  • ThenByDescending: utilizzato per eseguire ulteriori ordinamenti in ordine decrescente
  • Ordinato da: usato per definire l'ordine
  • OrderByDescending: utilizzato per definire l'ordine decrescente

Operatori di proiezione

  • SelectMany: usato per appiattire una raccolta gerarchica
  • Selezionare: utilizzato per identificare le proprietà da restituire

Operatori di concatenazione

  • concat: utilizzato per concatenare due raccolte

Così quello che ora?

LINQ ha dimostrato di essere molto utile per l'interrogazione di oggetti, e la sintassi simile a SQL lo rende facile
impara e usa Inoltre, il vasto numero di operatori standard consente di concatenare un numero di operatori
per eseguire query complesse. In un follow-up di questo tutorial, esamineremo in che modo LINQ può essere utilizzato
database di query e contenuto XML ...

Vendi script e componenti .NET su CodeCanyon



  • Seguici su Twitter o iscriviti al feed Nettuts + RSS per i migliori tutorial di sviluppo web sul web.