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.
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.
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:
ElencoListOfCars = 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:
IEnumerableQueryResult = 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"
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.
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:
IEnumerableQueryResult = dalla macchina in ListOfCars seleziona il nuovo CarOwner owner_name = car.owner;
Nel codice precedente, il tipo del risultato della query è dichiarato come
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.
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.
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.
IEnumerableQueryResult = 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à.
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.
IEnumerableQueryResult = 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:
IEnumerableQueryResult = dalla macchina in ListOfCars orderby car.model discendente select car;
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à.
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:
ElencoListOfCars = 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.
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.
ElencoListOfCars = 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.
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.
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 ...