LINQ - Guida rapida
Gli sviluppatori di tutto il mondo hanno sempre riscontrato problemi nell'esecuzione di query sui dati a causa della mancanza di un percorso definito e hanno bisogno di padroneggiare un multiplo di tecnologie come SQL, Web Services, XQuery, ecc.
Introdotto in Visual Studio 2008 e progettato da Anders Hejlsberg, LINQ (Language Integrated Query) consente di scrivere query anche senza la conoscenza di linguaggi di query come SQL, XML ecc. Le query LINQ possono essere scritte per diversi tipi di dati.
Esempio di una query LINQ
C #
using System;
using System.Linq;
class Program {
static void Main() {
string[] words = {"hello", "wonderful", "LINQ", "beautiful", "world"};
//Get only short words
var shortWords = from word in words where word.Length <= 5 select word;
//Print each word out
foreach (var word in shortWords) {
Console.WriteLine(word);
}
Console.ReadLine();
}
}
VB
Module Module1
Sub Main()
Dim words As String() = {"hello", "wonderful", "LINQ", "beautiful", "world"}
' Get only short words
Dim shortWords = From word In words _ Where word.Length <= 5 _ Select word
' Print each word out.
For Each word In shortWords
Console.WriteLine(word)
Next
Console.ReadLine()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
hello
LINQ
world
Sintassi di LINQ
Esistono due sintassi di LINQ. Questi sono i seguenti.
Sintassi Lamda (metodo)
var longWords = words.Where( w ⇒ w.length > 10);
Dim longWords = words.Where(Function(w) w.length > 10)
Sintassi della query (comprensione)
var longwords = from w in words where w.length > 10;
Dim longwords = from w in words where w.length > 10
Tipi di LINQ
I tipi di LINQ sono menzionati di seguito in breve.
- LINQ to Objects
- LINQ to XML (XLINQ)
- LINQ to DataSet
- LINQ to SQL (DLINQ)
- LINQ to Entities
Oltre a quanto sopra, esiste anche un tipo LINQ denominato PLINQ che è il LINQ parallelo di Microsoft.
Architettura LINQ in .NET
LINQ ha un'architettura a 3 livelli in cui il livello superiore è costituito dalle estensioni del linguaggio e il livello inferiore è costituito da origini dati che sono in genere oggetti che implementano interfacce generiche IEnumerable <T> o IQueryable <T>. L'architettura è mostrata di seguito.
Espressioni di query
L'espressione di query non è altro che una query LINQ, espressa in una forma simile a quella di SQL con operatori di query come Select, Where e OrderBy. Le espressioni di query di solito iniziano con la parola chiave "Da".
Per accedere agli operatori di query LINQ standard, lo spazio dei nomi System.Query deve essere importato per impostazione predefinita. Queste espressioni vengono scritte all'interno di una sintassi di query dichiarativa che era C # 3.0.
Di seguito è riportato un esempio per mostrare un'operazione di query completa che consiste nella creazione di origini dati, definizione di espressioni di query ed esecuzione di query.
C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Operators {
class LINQQueryExpressions {
static void Main() {
// Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 };
// Define the query expression.
IEnumerable<int> scoreQuery = from score in scores where score > 80 select score;
// Execute the query.
foreach (int i in scoreQuery) {
Console.Write(i + " ");
}
Console.ReadLine();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
97 92 81
Metodi di estensione
Introdotti con .NET 3.5, i metodi di estensione sono dichiarati solo nelle classi statiche e consentono l'inclusione di metodi personalizzati negli oggetti per eseguire alcune operazioni di query precise per estendere una classe senza essere un membro effettivo di quella classe. Anche questi possono essere sovraccaricati.
In poche parole, i metodi di estensione vengono utilizzati per tradurre le espressioni di query in chiamate di metodi tradizionali (orientate agli oggetti).
Differenza tra LINQ e Stored procedure
Esiste una serie di differenze esistenti tra LINQ e le stored procedure. Queste differenze sono menzionate di seguito.
Le stored procedure sono molto più veloci di una query LINQ poiché seguono un piano di esecuzione previsto.
È facile evitare errori in fase di esecuzione durante l'esecuzione di una query LINQ rispetto a una stored procedure poiché la prima ha il supporto Intellisense di Visual Studio e il controllo completo dei tipi durante la compilazione.
LINQ consente il debug facendo uso del debugger .NET che non è nel caso delle stored procedure.
LINQ offre supporto per più database a differenza delle stored procedure, in cui è essenziale riscrivere il codice per diversi tipi di database.
La distribuzione della soluzione basata su LINQ è facile e semplice rispetto alla distribuzione di una serie di procedure memorizzate.
Necessità di LINQ
Prima di LINQ, era essenziale apprendere C #, SQL e varie API che uniscono entrambi per formare un'applicazione completa. Da allora, queste fonti di dati e linguaggi di programmazione affrontano una mancata corrispondenza di impedenza; si avverte la necessità di una codifica breve.
Di seguito è riportato un esempio di quante diverse tecniche sono state utilizzate dagli sviluppatori durante l'interrogazione di dati prima dell'avvento di LINQ.
SqlConnection sqlConnection = new SqlConnection(connectString);
SqlConnection.Open();
System.Data.SqlClient.SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "Select * from Customer";
return sqlCommand.ExecuteReader (CommandBehavior.CloseConnection)
È interessante notare che, al di fuori delle righe di codice presenti, la query viene definita solo dalle ultime due. Utilizzando LINQ, la stessa query di dati può essere scritta in un formato leggibile con codice colore come il seguente menzionato di seguito anche in un tempo molto minore.
Northwind db = new Northwind(@"C:\Data\Northwnd.mdf");
var query = from c in db.Customers select c;
Vantaggi di LINQ
LINQ offre una serie di vantaggi e tra questi il primo è la sua potente espressività che consente agli sviluppatori di esprimersi in modo dichiarativo. Di seguito vengono forniti alcuni degli altri vantaggi di LINQ.
LINQ offre l'evidenziazione della sintassi che si rivela utile per individuare gli errori durante la fase di progettazione.
LINQ offre IntelliSense che significa scrivere facilmente query più accurate.
La scrittura di codici è molto più veloce in LINQ e quindi anche i tempi di sviluppo vengono ridotti in modo significativo.
LINQ semplifica il debug grazie alla sua integrazione nel linguaggio C #.
La visualizzazione della relazione tra due tabelle è facile con LINQ grazie alla sua caratteristica gerarchica e questo consente di comporre query unendo più tabelle in meno tempo.
LINQ consente l'utilizzo di una singola sintassi LINQ durante l'esecuzione di query su molte origini dati diverse e ciò è principalmente dovuto alla sua base unitiva.
LINQ è estensibile, il che significa che è possibile utilizzare la conoscenza di LINQ per eseguire query su nuovi tipi di origini dati.
LINQ offre la possibilità di unire diverse origini dati in una singola query, nonché di suddividere problemi complessi in una serie di query brevi di facile debug.
LINQ offre una facile trasformazione per la conversione di un tipo di dati in un altro come la trasformazione dei dati SQL in dati XML.
Prima di iniziare con i programmi LINQ, è meglio comprendere le sfumature della configurazione di un ambiente LINQ. LINQ necessita di un framework .NET, una piattaforma rivoluzionaria per avere diversi tipi di applicazioni. Una query LINQ può essere scritta comodamente in C # o Visual Basic.
Microsoft offre strumenti per entrambi questi linguaggi, ovvero C # e Visual Basic tramite Visual Studio. I nostri esempi sono tutti compilati e scritti in Visual Studio 2010. Tuttavia, è disponibile anche l'edizione Visual Basic 2013. È l'ultima versione e presenta molte somiglianze con Visual Studio 2012.
Ottenere Visual Studio 2010 installato su Windows 7
Visual Studio può essere installato da un supporto di installazione come un DVD. Le credenziali di amministratore sono necessarie per installare correttamente Visual Basic 2010 sul sistema. È fondamentale scollegare tutte le USB rimovibili dal sistema prima dell'installazione, altrimenti l'installazione potrebbe non riuscire. Alcuni dei requisiti hardware essenziali per l'installazione sono i seguenti.
Requisiti hardware
- 1,6 GHz o più
- 1 GB di RAM
- 3 GB (spazio disponibile su disco rigido)
- Unità disco rigido da 5400 RPM
- Scheda video compatibile con DirectX 9
- Unità DVD-ROM
Fasi di installazione
Step 1 - Innanzitutto, dopo aver inserito il DVD con il pacchetto Visual Studio 2010, fare clic su Install or run program from your media che appare in una casella pop-up sullo schermo.
Step 2- Ora la configurazione per Visual Studio apparirà sullo schermo. ScegliereInstall Microsoft Visual Studio 2010.
Step 3- Non appena si fa clic, il processo verrà avviato e sullo schermo verrà visualizzata una finestra di configurazione. Dopo il completamento del caricamento dei componenti di installazione, che richiederà del tempo, fare clic suNext per passare alla fase successiva.
Step 4 - Questo è l'ultimo passaggio dell'installazione e apparirà una pagina iniziale in cui è sufficiente scegliere "Ho letto e accetto i termini di licenza" e fare clic su Next pulsante.
Step 5- Ora seleziona le funzionalità da installare dalla pagina delle opzioni che appare sullo schermo. Puoi scegliereFull o Customopzione. Se hai meno spazio su disco di quanto richiesto mostrato nei requisiti di spazio su disco, scegli Personalizzato.
Step 6- Quando scegli l'opzione Personalizzata, apparirà la seguente finestra. Seleziona le funzionalità che desideri installare e fai clicUpdate oppure andare al passaggio 7. Tuttavia, si consiglia di non utilizzare l'opzione personalizzata poiché in futuro potrebbero essere necessarie le funzionalità che si è scelto di non avere.
Step 7- Presto verrà mostrata una finestra pop-up e verrà avviata l'installazione che potrebbe richiedere molto tempo. Ricorda, questo serve per l'installazione di tutti i componenti.
Step 8- Infine, sarai in grado di visualizzare un messaggio in una finestra che l'installazione è stata completata con successo. ClicFinish.
Scrittura di programmi C # utilizzando LINQ in Visual Studio 2010
Avvia Visual Studio 2010 Ultimate Edition e scegli File seguito da Nuovo progetto dal menu.
Sullo schermo apparirà una nuova finestra di dialogo del progetto.
Ora scegli Visual C # come categoria sotto i modelli installati e quindi scegli Modello applicazione console come mostrato nella figura seguente.
Dai un nome al tuo progetto nella casella del nome in basso e premi OK.
Il nuovo progetto verrà visualizzato in Esplora soluzioni nella parte destra di una nuova finestra di dialogo sullo schermo.
Ora scegli Program.cs da Solution Explorer e puoi visualizzare il codice nella finestra dell'editor che inizia con "using System".
Qui puoi iniziare a codificare il tuo programma C # seguente.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HelloWorld {
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World")
Console.ReadKey();
}
}
}
Premi il tasto F5 ed esegui il progetto. Si consiglia vivamente di salvare il progetto scegliendoFile → Save All prima di eseguire il progetto.
Scrittura di programmi VB utilizzando LINQ in Visual Studio 2010
Avvia Visual Studio 2010 Ultimate Edition e scegli File seguito da Nuovo progetto dal menu.
Sullo schermo apparirà una nuova finestra di dialogo del progetto.
Ora scegli Visual Basic come categoria sotto i modelli installati e quindi scegli Modello applicazione console.
Dai un nome al tuo progetto nella casella del nome in basso e premi OK.
Otterrai una schermata con Module1.vb. Inizia a scrivere il tuo codice VB qui usando LINQ.
Module Module1
Sub Main()
Console.WriteLine("Hello World")
Console.ReadLine()
End Sub
End Module
Premi il tasto F5 ed esegui il progetto. Si consiglia vivamente di salvare il progetto scegliendoFile → Save All prima di eseguire il progetto.
Quando il codice precedente di C # o VB viene cimpilato ed eseguito, produce il seguente risultato:
Hello World
Un insieme di metodi di estensione che formano un modello di query è noto come operatori di query standard LINQ. Come elementi costitutivi delle espressioni di query LINQ, questi operatori offrono una gamma di funzionalità di query come filtro, ordinamento, proiezione, aggregazione e così via.
Gli operatori di query standard LINQ possono essere classificati nei seguenti in base alla loro funzionalità.
- Operatori di filtraggio
- Unisciti agli operatori
- Operazioni di proiezione
- Operatori di ordinamento
- Operatori di raggruppamento
- Conversions
- Concatenation
- Aggregation
- Operazioni quantificatrici
- Operazioni di partizione
- Operazioni di generazione
- Imposta operazioni
- Equality
- Operatori elemento
Operatori di filtraggio
Il filtraggio è un'operazione per limitare il set di risultati in modo che abbia solo elementi selezionati che soddisfano una particolare condizione.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
dove | Filtra i valori in base a una funzione predicato | dove | Dove |
OfType | Filtra i valori in base alla loro capacità di essere un tipo specificato | Non applicabile | Non applicabile |
Unisciti agli operatori
L'unione si riferisce a un'operazione in cui vengono prese di mira fonti di dati con relazioni difficili da seguire tra loro in modo diretto.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Aderire | L'operatore unisce due sequenze sulla base delle chiavi corrispondenti | partecipare ... a ... su ... uguale ... | Da x In ..., y In ... Dove xa = ya |
GroupJoin | Unisci due sequenze e raggruppa gli elementi corrispondenti | unirsi ... in ... su ... uguale a ... in ... | Partecipa al gruppo ... In ... On ... |
Operazioni di proiezione
La proiezione è un'operazione in cui un oggetto viene trasformato in una forma completamente nuova con solo proprietà specifiche.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Selezionare | L'operatore proietta i valori sulla base di una funzione di trasformazione | Selezionare | Selezionare |
Seleziona Molti | L'operatore proietta le sequenze di valori che si basano su una funzione di trasformazione e le appiattisce in una singola sequenza | Usa più clausole from | Utilizza più clausole From |
Operatori di ordinamento
Un'operazione di ordinamento consente di ordinare gli elementi di una sequenza sulla base di uno o più attributi.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Ordinato da | L'operatore ordina i valori in ordine crescente | ordinato da | Ordinato da |
OrderByDescending | L'operatore ordina i valori in ordine decrescente | orderby ... discendente | Ordina per ... decrescente |
Allora per | Esegue un ordinamento secondario in ordine crescente | ordinato da …, … | Ordinato da …, … |
ThenByDescending | Esegue un ordinamento secondario in ordine decrescente | orderby ..., ... discendente | Ordina per ..., ... decrescente |
Inversione | Esegue un'inversione dell'ordine degli elementi in una raccolta | Non applicabile | Non applicabile |
Operatori di raggruppamento
Gli operatori inseriscono i dati in alcuni gruppi in base a un attributo condiviso comune.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Raggruppa per | Organizza una sequenza di elementi in gruppi e restituiscili come una raccolta IEnumerable di tipo IGrouping <chiave, elemento> | gruppo ... per -o- gruppo ... per ... in ... | Group ... By ... Into ... |
ToLookup | Eseguire un'operazione di raggruppamento in cui viene restituita una sequenza di coppie di chiavi | Non applicabile | Non applicabile |
Conversioni
Gli operatori cambiano il tipo di oggetti di input e vengono utilizzati in una vasta gamma di applicazioni.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
AsEnumerable | Restituisce l'input digitato come IEnumerable <T> | Non applicabile | Non applicabile |
AsQueryable | Un IEnumerable (generico) viene convertito in un IQueryable (generico) | Non applicabile | Non applicabile |
Cast | Esegue il casting degli elementi di una raccolta in un tipo specificato | Utilizza una variabile di intervallo specificata in modo esplicito. Ad esempio: dalla stringa str in parole | Da ... As ... |
OfType | Filtra i valori in base al loro, a seconda della loro capacità di essere convertiti in un tipo particolare | Non applicabile | Non applicabile |
ToArray | Forza l'esecuzione della query e converte una raccolta in un array | Non applicabile | Non applicabile |
ToDictionary | Sulla base di una funzione di selezione della chiave, imposta gli elementi in un Dictionary <TKey, TValue> e forza l'esecuzione di una query LINQ | Non applicabile | Non applicabile |
Elencare | Forza l'esecuzione di una query convertendo una raccolta in un List <T> | Non applicabile | Non applicabile |
ToLookup | Forza l'esecuzione di una query e inserisce elementi in una ricerca <TKey, TElement> sulla base di una funzione di selettore chiave | Non applicabile | Non applicabile |
Concatenazione
Esegue la concatenazione di due sequenze ed è abbastanza simile all'operatore dell'Unione in termini di funzionamento, tranne per il fatto che questo non rimuove i duplicati.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Concat | Due sequenze vengono concatenate per la formazione di un'unica sequenza. | Non applicabile | Non applicabile |
Aggregazione
Esegue qualsiasi tipo di aggregazione desiderata e consente di creare aggregazioni personalizzate in LINQ.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Aggregato | Opera sui valori di una raccolta per eseguire un'operazione di aggregazione personalizzata | Non applicabile | Non applicabile |
Media | Viene calcolato il valore medio di una raccolta di valori | Non applicabile | Aggregato ... In ... Into Average () |
Contare | Conta gli elementi che soddisfano una funzione predicato all'interno della raccolta | Non applicabile | Aggrega ... In ... Into Count () |
LonCount | Conta gli elementi che soddisfano una funzione predicativa all'interno di una vasta raccolta | Non applicabile | Aggrega ... In ... Into LongCount () |
Max | Scopri il valore massimo all'interno di una collezione | Non applicabile | Aggrega ... In ... Into Max () |
Min | Scopri il valore minimo esistente all'interno di una collezione | Non applicabile | Aggrega ... In ... In Min () |
Somma | Trova la somma di valori all'interno di una raccolta | Non applicabile | Aggrega ... In ... Into Sum () |
Operazioni quantificatrici
Questi operatori restituiscono un valore booleano, ad esempio True o False, quando alcuni o tutti gli elementi all'interno di una sequenza soddisfano una condizione specifica.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Tutti | Restituisce un valore "True" se tutti gli elementi di una sequenza soddisfano una condizione del predicato | Non applicabile | Aggrega ... In ... Into All (...) |
Qualunque | Determina mediante la ricerca di una sequenza se qualsiasi elemento della stessa soddisfa una condizione specificata | Non applicabile | Aggrega ... In ... In qualsiasi () |
Contiene | Restituisce un valore "Vero" se rileva che un elemento specifico è presente in una sequenza se la sequenza non contiene quell'elemento specifico, viene restituito il valore "falso" | Non applicabile | Non applicabile |
Operatori di partizione
Dividi una sequenza di input in due sezioni separate senza riorganizzare gli elementi della sequenza e quindi restituirne uno.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Salta | Salta un numero specificato di elementi all'interno di una sequenza e restituisce quelli rimanenti | Non applicabile | Salta |
SkipWhile | Uguale a quello di Skip con l'unica eccezione che il numero di elementi da saltare è specificato da una condizione booleana | Non applicabile | Salta mentre |
Prendere | Prendi un numero specificato di elementi da una sequenza e salta quelli rimanenti | Non applicabile | Prendere |
TakeWhile | Uguale a quello di Take tranne per il fatto che il numero di elementi da prendere è specificato da una condizione booleana | Non applicabile | Prendi tempo |
Operazioni di generazione
Una nuova sequenza di valori viene creata dagli operatori generazionali.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
DefaultIfEmpty | Quando applicato a una sequenza vuota, genera un elemento predefinito all'interno di una sequenza | Non applicabile | Non applicabile |
Vuoto | Restituisce una sequenza di valori vuota ed è l'operatore generazionale più semplice | Non applicabile | Non applicabile |
Gamma | Genera una raccolta con una sequenza di numeri interi o numeri | Non applicabile | Non applicabile |
Ripetere | Genera una sequenza contenente valori ripetuti di una lunghezza specifica | Non applicabile | Non applicabile |
Imposta operazioni
Ci sono quattro operatori per le operazioni impostate, ognuno dei quali produce un risultato basato su criteri diversi.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
Distinto | Ottiene un elenco di valori univoci da una raccolta filtrando i dati duplicati, se presenti | Non applicabile | Distinto |
Tranne | Confronta i valori di due raccolte e restituisce quelli di una raccolta che non si trovano nell'altra | Non applicabile | Non applicabile |
Interseca | Restituisce l'insieme di valori trovati identici in due raccolte separate | Non applicabile | Non applicabile |
Unione | Combina il contenuto di due diverse raccolte in un unico elenco anche questo senza alcun contenuto duplicato | Non applicabile | Non applicabile |
Uguaglianza
Confronta due frasi (enumerabili) e determina se sono una corrispondenza esatta o meno.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
SequenceEqual | Restituisce un valore booleano se due sequenze sono identiche l'una all'altra | Non applicabile | Non applicabile |
Operatori elemento
Ad eccezione di DefaultIfEmpty, tutti gli altri otto operatori di elementi di query standard restituiscono un singolo elemento da una raccolta.
Mostra esempi
Operatore | Descrizione | Sintassi delle espressioni di query C # | Sintassi delle espressioni di query VB |
---|---|---|---|
ElementAt | Restituisce un elemento presente all'interno di un indice specifico in una raccolta | Non applicabile | Non applicabile |
ElementAtOrDefault | Uguale a ElementAt tranne per il fatto che restituisce anche un valore predefinito nel caso in cui l'indice specifico sia fuori intervallo | Non applicabile | Non applicabile |
Primo | Recupera il primo elemento all'interno di una raccolta o il primo elemento che soddisfa una condizione specifica | Non applicabile | Non applicabile |
FirstOrDefault | Uguale a First tranne per il fatto che restituisce anche un valore predefinito nel caso in cui non esistano tali elementi | Non applicabile | Non applicabile |
Scorso | Recupera l'ultimo elemento presente in una raccolta o l'ultimo elemento che soddisfa una condizione specifica | Non applicabile | Non applicabile |
LastOrDefault | Uguale a Last tranne per il fatto che restituisce anche un valore predefinito nel caso in cui non esista alcun elemento di questo tipo | Non applicabile | Non applicabile |
Single | Restituisce l'elemento solitario di una raccolta o l'elemento solitario che soddisfa una determinata condizione | Non applicabile | Non applicabile |
SingleOrDefault | Uguale a Single tranne che restituisce anche un valore predefinito se non esiste alcun elemento solitario di questo tipo | Non applicabile | Non applicabile |
DefaultIfEmpty | Restituisce un valore predefinito se la raccolta o l'elenco è vuoto o nullo | Non applicabile | Non applicabile |
LINQ to SQL offre un'infrastruttura (run-time) per la gestione dei dati relazionali come oggetti. È un componente della versione 3.5 di .NET Framework e traduce abilmente in SQL le query integrate nel linguaggio del modello a oggetti. Queste query vengono quindi inviate al database ai fini dell'esecuzione. Dopo aver ottenuto i risultati dal database, LINQ to SQL li traduce nuovamente in oggetti.
Introduzione di LINQ To SQL
Per la maggior parte degli sviluppatori ASP.NET, LINQ to SQL (noto anche come DLINQ) è una parte elettrizzante di Language Integrated Query in quanto consente di eseguire query sui dati nel database di SQL Server utilizzando le normali espressioni LINQ. Consente inoltre di aggiornare, eliminare e inserire dati, ma l'unico inconveniente di cui soffre è la sua limitazione al database del server SQL. Tuttavia, ci sono molti vantaggi di LINQ to SQL rispetto ad ADO.NET come la complessità ridotta, poche righe di codice e molti altri.
Di seguito è riportato un diagramma che mostra l'architettura di esecuzione di LINQ to SQL.
Come utilizzare LINQ to SQL?
Step 1- Creare una nuova "connessione dati" con il server di database. Visualizza & arrar; Esplora server & arrar; Connessioni dati & arrar; Aggiungi connessione
Step 2 - Aggiungi LINQ al file di classe SQL
Step 3 - Selezionare le tabelle dal database e trascinarle nel nuovo file di classe LINQ to SQL.
Step 4 - Aggiunte tabelle al file di classe.
Esecuzione di query con LINQ to SQL
Le regole per l'esecuzione di una query con LINQ to SQL sono simili a quelle di una query LINQ standard, ovvero la query viene eseguita differita o immediata. Esistono vari componenti che svolgono un ruolo nell'esecuzione di una query con LINQ to SQL e questi sono i seguenti.
LINQ to SQL API - richiede l'esecuzione di query per conto di un'applicazione e la invia a LINQ al provider SQL.
LINQ to SQL Provider - converte la query in Transact SQL (T-SQL) e invia la nuova query al provider ADO per l'esecuzione.
ADO Provider - Dopo l'esecuzione della query, inviare i risultati sotto forma di un DataReader a LINQ a SQL Provider che a sua volta lo converte in una forma di oggetto utente.
Va notato che prima di eseguire una query LINQ to SQL, è fondamentale connettersi all'origine dati tramite la classe DataContext.
Inserisci, aggiorna ed elimina utilizzando LINQ To SQL
Aggiungi O Inserisci
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
//Create new Employee
Employee newEmployee = new Employee();
newEmployee.Name = "Michael";
newEmployee.Email = "[email protected]";
newEmployee.ContactNo = "343434343";
newEmployee.DepartmentId = 3;
newEmployee.Address = "Michael - USA";
//Add new Employee to database
db.Employees.InsertOnSubmit(newEmployee);
//Save changes to Database.
db.SubmitChanges();
//Get new Inserted Employee
Employee insertedEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("Michael"));
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}, Address = {4}",
insertedEmployee.EmployeeId, insertedEmployee.Name, insertedEmployee.Email,
insertedEmployee.ContactNo, insertedEmployee.Address);
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim newEmployee As New Employee()
newEmployee.Name = "Michael"
newEmployee.Email = "[email protected]"
newEmployee.ContactNo = "343434343"
newEmployee.DepartmentId = 3
newEmployee.Address = "Michael - USA"
db.Employees.InsertOnSubmit(newEmployee)
db.SubmitChanges()
Dim insertedEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("Michael"))
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3},
Address = {4}", insertedEmployee.EmployeeId, insertedEmployee.Name,
insertedEmployee.Email, insertedEmployee.ContactNo, insertedEmployee.Address)
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Emplyee ID = 4, Name = Michael, Email = [email protected], ContactNo =
343434343, Address = Michael - USA
Press any key to continue.
Aggiornare
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
//Get Employee for update
Employee employee = db.Employees.FirstOrDefault(e =>e.Name.Equals("Michael"));
employee.Name = "George Michael";
employee.Email = "[email protected]";
employee.ContactNo = "99999999";
employee.DepartmentId = 2;
employee.Address = "Michael George - UK";
//Save changes to Database.
db.SubmitChanges();
//Get Updated Employee
Employee updatedEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("George Michael"));
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}, Address = {4}",
updatedEmployee.EmployeeId, updatedEmployee.Name, updatedEmployee.Email,
updatedEmployee.ContactNo, updatedEmployee.Address);
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim employee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("Michael"))
employee.Name = "George Michael"
employee.Email = "[email protected]"
employee.ContactNo = "99999999"
employee.DepartmentId = 2
employee.Address = "Michael George - UK"
db.SubmitChanges()
Dim updatedEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("George Michael"))
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3},
Address = {4}", updatedEmployee.EmployeeId, updatedEmployee.Name,
updatedEmployee.Email, updatedEmployee.ContactNo, updatedEmployee.Address)
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o Vb viene compilato ed eseguito, produce il seguente risultato:
Emplyee ID = 4, Name = George Michael, Email = [email protected], ContactNo =
999999999, Address = Michael George - UK
Press any key to continue.
Elimina
C#
using System;
using System.Linq;
namespace LINQtoSQL {
class LinqToSQLCRUD {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
LinqToSQLDataContext db = newLinqToSQLDataContext(connectString);
//Get Employee to Delete
Employee deleteEmployee = db.Employees.FirstOrDefault(e ⇒e.Name.Equals("George Michael"));
//Delete Employee
db.Employees.DeleteOnSubmit(deleteEmployee);
//Save changes to Database.
db.SubmitChanges();
//Get All Employee from Database
var employeeList = db.Employees;
foreach (Employee employee in employeeList) {
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}",
employee.EmployeeId, employee.Name, employee.Email, employee.ContactNo);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Module Module1
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim db As New LinqToSQLDataContext(connectString)
Dim deleteEmployee As Employee = db.Employees.FirstOrDefault(Function(e) e.Name.Equals("George Michael"))
db.Employees.DeleteOnSubmit(deleteEmployee)
db.SubmitChanges()
Dim employeeList = db.Employees
For Each employee As Employee In employeeList
Console.WriteLine("Employee Id = {0} , Name = {1}, Email = {2}, ContactNo = {3}",
employee.EmployeeId, employee.Name, employee.Email, employee.ContactNo)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Emplyee ID = 1, Name = William, Email = [email protected], ContactNo = 999999999
Emplyee ID = 2, Name = Miley, Email = [email protected], ContactNo = 999999999
Emplyee ID = 3, Name = Benjamin, Email = [email protected], ContactNo =
Press any key to continue.
LINQ to Objects offre l'utilizzo di qualsiasi query LINQ che supporta IEnumerable <T> per accedere alle raccolte di dati in memoria senza alcuna necessità di provider LINQ (API) come nel caso di LINQ to SQL o LINQ to XML.
Introduzione di LINQ to Objects
Le query in LINQ to Objects restituiscono variabili di tipo in genere solo IEnumerable <T>. In breve, LINQ to Objects offre un nuovo approccio alle raccolte come in precedenza, era fondamentale scrivere una codifica lunga (cicli foreach di grande complessità) per il recupero dei dati da una raccolta che ora viene sostituita dalla scrittura di codice dichiarativo che descrive chiaramente i dati desiderati che è necessario per recuperare.
Ci sono anche molti vantaggi di LINQ to Objects rispetto ai tradizionali cicli foreach come maggiore leggibilità, filtri potenti, capacità di raggruppamento, ordinamento migliorato con codice applicativo minimo. Tali query LINQ sono anche di natura più compatta e possono essere trasferite a qualsiasi altra origine dati senza alcuna modifica o con una piccola modifica.
Di seguito è riportato un semplice esempio di LINQ to Objects:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQtoObjects {
class Program {
static void Main(string[] args) {
string[] tools = { "Tablesaw", "Bandsaw", "Planer", "Jointer", "Drill", "Sander" };
var list = from t in tools select t;
StringBuilder sb = new StringBuilder();
foreach (string s in list) {
sb.Append(s + Environment.NewLine);
}
Console.WriteLine(sb.ToString(), "Tools");
Console.ReadLine();
}
}
}
Nell'esempio, una matrice di stringhe (strumenti) viene utilizzata come raccolta di oggetti da interrogare utilizzando LINQ to Objects.
Objects query is:
var list = from t in tools select t;
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
Tablesaw
Bandsaw
Planer
Jointer
Drill
Sander
Esecuzione di query nelle raccolte di memoria tramite LINQ to Objects
C #
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQtoObjects {
class Department {
public int DepartmentId { get; set; }
public string Name { get; set; }
}
class LinqToObjects {
static void Main(string[] args) {
List<Department> departments = new List<Department>();
departments.Add(new Department { DepartmentId = 1, Name = "Account" });
departments.Add(new Department { DepartmentId = 2, Name = "Sales" });
departments.Add(new Department { DepartmentId = 3, Name = "Marketing" });
var departmentList = from d in departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Module Module1
Sub Main(ByVal args As String())
Dim account As New Department With {.Name = "Account", .DepartmentId = 1}
Dim sales As New Department With {.Name = "Sales", .DepartmentId = 2}
Dim marketing As New Department With {.Name = "Marketing", .DepartmentId = 3}
Dim departments As New System.Collections.Generic.List(Of Department)(New Department() {account, sales, marketing})
Dim departmentList = From d In departments
For Each dept In departmentList
Console.WriteLine("Department Id = {0} , Department Name = {1}", dept.DepartmentId, dept.Name)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Class Department
Public Property Name As String
Public Property DepartmentId As Integer
End Class
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Department Id = 1, Department Name = Account
Department Id = 2, Department Name = Sales
Department Id = 3, Department Name = Marketing
Press any key to continue.
Un set di dati offre una rappresentazione dei dati estremamente utile in memoria e viene utilizzato per una vasta gamma di applicazioni basate sui dati. LINQ to Dataset come una delle tecnologie di LINQ to ADO.NET facilita l'esecuzione di query sui dati di un set di dati in modo semplice e migliora la produttività.
Introduzione di LINQ To Dataset
LINQ to Dataset ha semplificato il compito di eseguire query per gli sviluppatori. Non hanno bisogno di scrivere query in un linguaggio di query specifico, invece lo stesso può essere scritto in linguaggio di programmazione. LINQ to Dataset può essere utilizzato anche per eseguire query in cui i dati vengono consolidati da più origini dati. Inoltre, non è necessario alcun provider LINQ come LINQ to SQL e LINQ to XML per l'accesso ai dati da raccolte in memoria.
Di seguito è riportato un semplice esempio di query LINQ to Dataset in cui viene prima ottenuta un'origine dati e quindi il set di dati viene riempito con due tabelle di dati. Viene stabilita una relazione tra entrambe le tabelle e viene creata una query LINQ su entrambe le tabelle mediante la clausola di join. Infine, il ciclo foreach viene utilizzato per visualizzare i risultati desiderati.
C #
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LINQtoDataset {
class Program {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
string sqlSelect = "SELECT * FROM Department;" + "SELECT * FROM Employee;";
// Create the data adapter to retrieve data from the database
SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connectString);
// Create table mappings
da.TableMappings.Add("Table", "Department");
da.TableMappings.Add("Table1", "Employee");
// Create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);
DataRelation dr = ds.Relations.Add("FK_Employee_Department",
ds.Tables["Department"].Columns["DepartmentId"],
ds.Tables["Employee"].Columns["DepartmentId"]);
DataTable department = ds.Tables["Department"];
DataTable employee = ds.Tables["Employee"];
var query = from d in department.AsEnumerable()
join e in employee.AsEnumerable()
on d.Field<int>("DepartmentId") equals
e.Field<int>("DepartmentId")
select new {
EmployeeId = e.Field<int>("EmployeeId"),
Name = e.Field<string>("Name"),
DepartmentId = d.Field<int>("DepartmentId"),
DepartmentName = d.Field<string>("Name")
};
foreach (var q in query) {
Console.WriteLine("Employee Id = {0} , Name = {1} , Department Name = {2}",
q.EmployeeId, q.Name, q.DepartmentName);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Data.SqlClient
Imports System.Linq
Module LinqToDataSet
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim sqlSelect As String = "SELECT * FROM Department;" + "SELECT * FROM Employee;"
Dim sqlCnn As SqlConnection = New SqlConnection(connectString)
sqlCnn.Open()
Dim da As New SqlDataAdapter
da.SelectCommand = New SqlCommand(sqlSelect, sqlCnn)
da.TableMappings.Add("Table", "Department")
da.TableMappings.Add("Table1", "Employee")
Dim ds As New DataSet()
da.Fill(ds)
Dim dr As DataRelation = ds.Relations.Add("FK_Employee_Department", ds.Tables("Department").Columns("DepartmentId"), ds.Tables("Employee").Columns("DepartmentId"))
Dim department As DataTable = ds.Tables("Department")
Dim employee As DataTable = ds.Tables("Employee")
Dim query = From d In department.AsEnumerable()
Join e In employee.AsEnumerable() On d.Field(Of Integer)("DepartmentId") Equals
e.Field(Of Integer)("DepartmentId")
Select New Person With { _
.EmployeeId = e.Field(Of Integer)("EmployeeId"),
.EmployeeName = e.Field(Of String)("Name"),
.DepartmentId = d.Field(Of Integer)("DepartmentId"),
.DepartmentName = d.Field(Of String)("Name")
}
For Each e In query
Console.WriteLine("Employee Id = {0} , Name = {1} , Department Name = {2}", e.EmployeeId, e.EmployeeName, e.DepartmentName)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Class Person
Public Property EmployeeId As Integer
Public Property EmployeeName As String
Public Property DepartmentId As Integer
Public Property DepartmentName As String
End Class
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Employee Id = 1, Name = William, Department Name = Account
Employee Id = 2, Name = Benjamin, Department Name = Account
Employee Id = 3, Name = Miley, Department Name = Sales
Press any key to continue.
Interrogazione del set di dati utilizzando LinQ al set di dati
Prima di iniziare a eseguire query su un set di dati utilizzando LINQ to Dataset, è fondamentale caricare i dati in un set di dati e ciò viene eseguito utilizzando la classe DataAdapter o LINQ to SQL. La formulazione di query utilizzando LINQ to Dataset è abbastanza simile alla formulazione di query utilizzando LINQ insieme ad altre origini dati abilitate per LINQ.
Query su tabella singola
Nella seguente query a tabella singola, tutti gli ordini in linea vengono raccolti dalla tabella SalesOrderHeaderTtable e quindi l'ID dell'ordine, la data dell'ordine e il numero dell'ordine vengono visualizzati come output.
C#
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinqToDataset {
class SingleTable {
static void Main(string[] args) {
string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
string sqlSelect = "SELECT * FROM Department;";
// Create the data adapter to retrieve data from the database
SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connectString);
// Create table mappings
da.TableMappings.Add("Table", "Department");
// Create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);
DataTable department = ds.Tables["Department"];
var query = from d in department.AsEnumerable()
select new {
DepartmentId = d.Field<int>("DepartmentId"),
DepartmentName = d.Field<string>("Name")
};
foreach (var q in query) {
Console.WriteLine("Department Id = {0} , Name = {1}",
q.DepartmentId, q.DepartmentName);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Data.SqlClient
Imports System.Linq
Module LinqToDataSet
Sub Main()
Dim connectString As String = System.Configuration.ConfigurationManager.ConnectionStrings("LinqToSQLDBConnectionString").ToString()
Dim sqlSelect As String = "SELECT * FROM Department;"
Dim sqlCnn As SqlConnection = New SqlConnection(connectString)
sqlCnn.Open()
Dim da As New SqlDataAdapter
da.SelectCommand = New SqlCommand(sqlSelect, sqlCnn)
da.TableMappings.Add("Table", "Department")
Dim ds As New DataSet()
da.Fill(ds)
Dim department As DataTable = ds.Tables("Department")
Dim query = From d In department.AsEnumerable()
Select New DepartmentDetail With {
.DepartmentId = d.Field(Of Integer)("DepartmentId"),
.DepartmentName = d.Field(Of String)("Name")
}
For Each e In query
Console.WriteLine("Department Id = {0} , Name = {1}", e.DepartmentId, e.DepartmentName)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
Public Class DepartmentDetail
Public Property DepartmentId As Integer
Public Property DepartmentName As String
End Class
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Department Id = 1, Name = Account
Department Id = 2, Name = Sales
Department Id = 3, Name = Pre-Sales
Department Id = 4, Name = Marketing
Press any key to continue.
LINQ to XML offre facile accessibilità a tutte le funzionalità LINQ come operatori di query standard, interfaccia di programmazione, ecc. Integrato nel framework .NET, LINQ to XML fa anche il miglior uso delle funzionalità del framework .NET come il debug, il controllo in fase di compilazione, la digitazione forte e molti altri da dire.
Introduzione di LINQ to XML
Durante l'utilizzo di LINQ to XML, il caricamento di documenti XML in memoria è facile e più semplice è l'esecuzione di query e la modifica dei documenti. È anche possibile salvare su disco documenti XML esistenti in memoria e serializzarli. Elimina la necessità per uno sviluppatore di apprendere il linguaggio di query XML che è alquanto complesso.
LINQ to XML ha il suo potere nello spazio dei nomi System.Xml.Linq. Questo ha tutte le 19 classi necessarie per lavorare con XML. Queste classi sono le seguenti.
- XAttribute
- XCData
- XComment
- XContainer
- XDeclaration
- XDocument
- XDocumentType
- XElement
- XName
- XNamespace
- XNode
- XNodeDocumentOrderComparer
- XNodeEqualityComparer
- XObject
- XObjectChange
- XObjectChangeEventArgs
- XObjectEventHandler
- XProcessingInstruction
- XText
Leggere un file XML utilizzando LINQ
C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(ByVal args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Department Name - Account
Department Name - Sales
Department Name - Pre-Sales
Department Name - Marketing
Press any key to continue.
Aggiungi nuovo nodo
C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
//Add new Element
xdoc.Element("Departments").Add(new XElement("Department", "Finance"));
//Add new Element at First
xdoc.Element("Departments").AddFirst(new XElement("Department", "Support"));
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(ByVal args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
xdoc.Element("Departments").Add(New XElement("Department", "Finance"))
xdoc.Element("Departments").AddFirst(New XElement("Department", "Support"))
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Department Name - Support
Department Name - Account
Department Name - Sales
Department Name - Pre-Sales
Department Name - Marketing
Department Name - Finance
Press any key to continue.
Eliminazione di un nodo particolare
C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LINQtoXML {
class ExampleOfXML {
static void Main(string[] args) {
string myXML = @"<Departments>
<Department>Support</Department>
<Department>Account</Department>
<Department>Sales</Department>
<Department>Pre-Sales</Department>
<Department>Marketing</Department>
<Department>Finance</Department>
</Departments>";
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(myXML);
//Remove Sales Department
xdoc.Descendants().Where(s =>s.Value == "Sales").Remove();
var result = xdoc.Element("Departments").Descendants();
foreach (XElement item in result) {
Console.WriteLine("Department Name - " + item.Value);
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
VB
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Module Module1
Sub Main(args As String())
Dim myXML As String = "<Departments>" & vbCr & vbLf &
"<Department>Support</Department>" & vbCr & vbLf &
"<Department>Account</Department>" & vbCr & vbLf &
"<Department>Sales</Department>" & vbCr & vbLf &
"<Department>Pre-Sales</Department>" & vbCr & vbLf &
"<Department>Marketing</Department>" & vbCr & vbLf &
"<Department>Finance</Department>" & vbCr & vbLf &
"</Departments>"
Dim xdoc As New XDocument()
xdoc = XDocument.Parse(myXML)
xdoc.Descendants().Where(Function(s) s.Value = "Sales").Remove()
Dim result = xdoc.Element("Departments").Descendants()
For Each item As XElement In result
Console.WriteLine("Department Name - " + item.Value)
Next
Console.WriteLine(vbLf & "Press any key to continue.")
Console.ReadKey()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
Department Name - Support
Department Name - Account
Department Name - Pre-Sales
Department Name - Marketing
Department Name - Finance
Press any key to continue.
Una parte di ADO.NET Entity Framework, LINQ to Entities è più flessibile di LINQ to SQL, ma non è molto popolare a causa della sua complessità e mancanza di funzionalità chiave. Tuttavia, non ha le limitazioni di LINQ to SQL che consente la query di dati solo nel database del server SQL poiché LINQ to Entities facilita la query di dati in un gran numero di fornitori di dati come Oracle, MySQL, ecc.
Inoltre, ha un importante supporto da ASP.Net, nel senso che gli utenti possono utilizzare un controllo dell'origine dati per eseguire una query tramite LINQ a Entities e facilita l'associazione dei risultati senza alcuna necessità di codifica aggiuntiva.
LINQ to Entities è diventato per questi vantaggi il meccanismo standard per l'utilizzo di LINQ sui database al giorno d'oggi. È anche possibile con LINQ to Entities modificare i dettagli dei dati richiesti e eseguire facilmente un aggiornamento batch. Il fatto più interessante di LINQ to Entities è che ha la stessa sintassi di SQL e ha anche lo stesso gruppo di operatori di query standard come Join, Select, OrderBy, ecc.
Processo di creazione ed esecuzione di query LINQ to Entities
Costruzione di un ObjectQuery istanza da un file ObjectContext (Connessione entità)
Composizione di una query in C # o Visual Basic (VB) utilizzando l'istanza appena costruita
Conversione degli operatori di query standard di LINQ e delle espressioni LINQ in alberi di comando
Esecuzione della query passando direttamente al client le eccezioni riscontrate
Restituendo al client tutti i risultati della query
ObjectContext è qui la classe principale che consente l'interazione con Entity Data Modelo in altre parole funge da bridge che collega LINQ al database. Gli alberi dei comandi sono qui rappresentazioni delle query con compatibilità con il framework Entity.
L'Entity Framework, d'altra parte, è in realtà Object Relational Mapperabbreviato generalmente come ORM dagli sviluppatori che fa la generazione di oggetti di business e entità secondo le tabelle del database e facilita varie operazioni di base come creare, aggiornare, eliminare e leggere. La figura seguente mostra il framework di entità e i suoi componenti.
Esempio di ADD, UPDATE e DELETE utilizzando LINQ con Entity Model
Per prima cosa aggiungi Entity Model seguendo i passaggi seguenti.
Step 1- Fare clic con il tasto destro sul progetto e fare clic su Aggiungi nuovo elemento per aprire la finestra come di seguito. Selezionare ADO.NET Entity Data Model e specificare il nome e fare clic su Aggiungi.
Step 2 - Seleziona Generate from database.
Step 3 - Scegli Connessione database dal menu a discesa.
Step 4 - Seleziona tutte le tabelle.
Ora scrivi il codice seguente.
using DataAccess;
using System;
using System.Linq;
namespace LINQTOSQLConsoleApp {
public class LinqToEntityModel {
static void Main(string[] args) {
using (LinqToSQLDBEntities context = new LinqToSQLDBEntities()) {
//Get the List of Departments from Database
var departmentList = from d in context.Departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
//Add new Department
DataAccess.Department department = new DataAccess.Department();
department.Name = "Support";
context.Departments.Add(department);
context.SaveChanges();
Console.WriteLine("Department Name = Support is inserted in Database");
//Update existing Department
DataAccess.Department updateDepartment = context.Departments.FirstOrDefault(d ⇒d.DepartmentId == 1);
updateDepartment.Name = "Account updated";
context.SaveChanges();
Console.WriteLine("Department Name = Account is updated in Database");
//Delete existing Department
DataAccess.Department deleteDepartment = context.Departments.FirstOrDefault(d ⇒d.DepartmentId == 3);
context.Departments.Remove(deleteDepartment);
context.SaveChanges();
Console.WriteLine("Department Name = Pre-Sales is deleted in Database");
//Get the Updated List of Departments from Database
departmentList = from d in context.Departments
select d;
foreach (var dept in departmentList) {
Console.WriteLine("Department Id = {0} , Department Name = {1}",
dept.DepartmentId, dept.Name);
}
}
Console.WriteLine("\nPress any key to continue.");
Console.ReadKey();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
Il termine "espressione lambda" ha derivato il suo nome da "lambda" calcolo che a sua volta è una notazione matematica applicata per definire le funzioni. Le espressioni Lambda come parte eseguibile di un'equazione LINQ traducono la logica in un modo in fase di esecuzione in modo che possa passare comodamente all'origine dati. Tuttavia, le espressioni lambda non si limitano solo a trovare applicazioni solo in LINQ.
Queste espressioni sono espresse dalla seguente sintassi:
(Input parameters) ⇒ Expression or statement block
Ecco un esempio di un'espressione lambda:
y ⇒ y * y
L'espressione precedente specifica un parametro denominato y e il valore di y è al quadrato. Tuttavia, non è possibile eseguire un'espressione lambda in questa forma. Di seguito è riportato un esempio di un'espressione lambda in C #.
C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
delegate int del(int i);
static void Main(string[] args) {
del myDelegate = y ⇒ y * y;
int j = myDelegate(5);
Console.WriteLine(j);
Console.ReadLine();
}
}
}
VB
Module Module1
Private Delegate Function del(ByVal i As Integer) As Integer
Sub Main(ByVal args As String())
Dim myDelegate As del = Function(y) y * y
Dim j As Integer = myDelegate(5)
Console.WriteLine(j)
Console.ReadLine()
End Sub
End Module
Quando il codice precedente di C # o VB viene compilato ed eseguito, produce il seguente risultato:
25
Espressione Lambda
Poiché l'espressione nella sintassi dell'espressione lambda mostrata sopra si trova sul lato destro, questi sono noti anche come espressione lambda.
Async Lambdas
L'espressione lambda creata incorporando l'elaborazione asincrona mediante l'uso della parola chiave async è nota come lambda asincrona. Di seguito è riportato un esempio di lambda asincrono.
Func<Task<string>> getWordAsync = async()⇒ “hello”;
Lambda negli operatori di query standard
Un'espressione lambda all'interno di un operatore di query viene valutata dallo stesso su richiesta e lavora continuamente su ciascuno degli elementi nella sequenza di input e non sull'intera sequenza. Agli sviluppatori è consentito dall'espressione Lambda di alimentare la propria logica negli operatori di query standard. Nell'esempio seguente, lo sviluppatore ha utilizzato l'operatore "Where" per recuperare i valori dispari dall'elenco fornito utilizzando un'espressione lambda.
C #
//Get the average of the odd Fibonacci numbers in the series...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
static void Main(string[] args) {
int[] fibNum = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
double averageValue = fibNum.Where(num ⇒ num % 2 == 1).Average();
Console.WriteLine(averageValue);
Console.ReadLine();
}
}
}
VB
Module Module1
Sub Main()
Dim fibNum As Integer() = {1, 1, 2, 3, 5, 8, 13, 21, 34}
Dim averageValue As Double = fibNum.Where(Function(num) num Mod 2 = 1).Average()
Console.WriteLine(averageValue)
Console.ReadLine()
End Sub
End Module
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
7.33333333333333
Digitare inferenza in Lambda
In C #, l'inferenza del tipo viene utilizzata convenientemente in una varietà di situazioni e anche senza specificare i tipi in modo esplicito. Tuttavia, nel caso di un'espressione lambda, l'inferenza del tipo funzionerà solo quando ogni tipo è stato specificato poiché il compilatore deve essere soddisfatto. Consideriamo il seguente esempio.
delegate int Transformer (int i);
Qui il compilatore utilizza l'inferenza del tipo per attingere al fatto che x è un numero intero e questo viene fatto esaminando il tipo di parametro del Transformer.
Ambito variabile nell'espressione Lambda
Esistono alcune regole durante l'utilizzo dell'ambito variabile in un'espressione lambda come le variabili che vengono avviate all'interno di un'espressione lambda non sono pensate per essere visibili in un metodo esterno. Esiste anche una regola per cui una variabile acquisita non deve essere raccolta in Garbage Collection a meno che il delegato che fa riferimento alla stessa non diventi idoneo per l'atto di Garbage Collection. Inoltre, esiste una regola che proibisce a un'istruzione return all'interno di un'espressione lambda di causare la restituzione di un metodo di inclusione.
Di seguito è riportato un esempio per dimostrare l'ambito della variabile nell'espressione lambda.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lambdaexample {
class Program {
delegate bool D();
delegate bool D2(int i);
class Test {
D del;
D2 del2;
public void TestMethod(int input) {
int j = 0;
// Initialize the delegates with lambda expressions.
// Note access to 2 outer variables.
// del will be invoked within this method.
del = () ⇒ { j = 10; return j > input; };
// del2 will be invoked after TestMethod goes out of scope.
del2 = (x) ⇒ { return x == j; };
// Demonstrate value of j:
// The delegate has not been invoked yet.
Console.WriteLine("j = {0}", j); // Invoke the delegate.
bool boolResult = del();
Console.WriteLine("j = {0}. b = {1}", j, boolResult);
}
static void Main() {
Test test = new Test();
test.TestMethod(5);
// Prove that del2 still has a copy of
// local variable j from TestMethod.
bool result = test.del2(10);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
j = 0
j = 10. b = True
True
Albero delle espressioni
Le espressioni lambda vengono utilizzate in Expression Treecostruzione ampiamente. Un albero delle espressioni fornisce il codice in una struttura dati simile a un albero in cui ogni nodo è esso stesso un'espressione come una chiamata a un metodo o può essere un'operazione binaria come x <y. Di seguito è riportato un esempio di utilizzo dell'espressione lambda per la costruzione di un albero delle espressioni.
Istruzione Lambda
C'è anche statement lambdasconsistono in due o tre affermazioni, ma non vengono utilizzati nella costruzione di alberi di espressione. Un'istruzione return deve essere scritta in un'istruzione lambda.
Sintassi dell'istruzione lambda
(params)⇒ {statements}
Esempio di un'istruzione lambda
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace lambdaexample {
class Program {
static void Main(string[] args) {
int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };
foreach (int i in source.Where(x ⇒
{
if (x <= 3)
return true;
else if (x >= 7)
return true;
return false;
}
))
Console.WriteLine(i);
Console.ReadLine();
}
}
}
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
3
8
1
7
9
2
8
Le lambda vengono utilizzate come argomenti nelle query LINQ basate su metodi e non è mai consentito di avere un posto sul lato sinistro di operatori come is o asproprio come i metodi anonimi. Sebbene le espressioni Lambda siano metodi anonimi molto simili, questi non sono affatto limitati per essere utilizzati solo come delegati.
Punti da ricordare durante l'utilizzo di espressioni lambda
Un'espressione lambda può restituire un valore e può avere parametri.
I parametri possono essere definiti in una miriade di modi con un'espressione lambda.
Se è presente una singola istruzione in un'espressione lambda, non è necessario utilizzare parentesi graffe, mentre se sono presenti più istruzioni, è essenziale scrivere le parentesi graffe e il valore restituito.
Con le espressioni lambda, è possibile accedere alle variabili presenti all'esterno del blocco dell'espressione lambda tramite una funzionalità nota come chiusura. L'uso della chiusura deve essere fatto con cautela per evitare qualsiasi problema.
È impossibile eseguire codice non sicuro all'interno di qualsiasi espressione lambda.
Le espressioni lambda non sono pensate per essere utilizzate sul lato sinistro dell'operatore.
In quanto set di estensioni .NET framework, LINQ è il meccanismo preferito per l'accesso ai dati da parte degli sviluppatori ASP.NET. ASP.NET 3.5 dispone di uno strumento integrato di controllo LINQDataSource che consente l'utilizzo di LINQ facilmente in ASP.NET. ASP.NET utilizza il controllo sopra menzionato come origine dati. I progetti nella vita reale comprendono principalmente siti Web o applicazioni Windows e quindi per comprendere meglio il concetto di LINQ con ASP.NET, iniziamo con la creazione di un sito Web ASP.NET che utilizzi le funzionalità di LINQ.
Per questo, è essenziale installare Visual Studio e .NET Framework sul sistema. Dopo aver aperto Visual Studio, vai su File → Nuovo → Sito web. Si aprirà una finestra pop-up come mostrato nella figura sottostante.
Ora, sotto i modelli sul lato sinistro, ci saranno due opzioni di lingua per creare il sito web. ScegliereVisual C# e seleziona ASP.NET Empty Web Site.
Seleziona la cartella in cui desideri salvare il nuovo sito Web sul tuo sistema. Quindi premereOK e così via Solution Explorerappare sullo schermo contenente tutti i file web. Fare clic con il pulsante destro del mouse su Default.aspx in Esplora soluzioni e scegliere Visualizza nel browser per visualizzare il sito Web ASP.NET predefinito nel browser. Presto il tuo nuovo sito Web ASP.NET si aprirà nel browser web, come mostrato nello screenshot seguente.
.aspx è infatti la principale estensione di file utilizzata nei siti Web ASP.NET. Visual Studio per impostazione predefinita crea tutte le pagine necessarie per un sito Web di base comeHome page e About Uspagina in cui puoi posizionare comodamente i tuoi contenuti. Il codice per il sito web viene generato automaticamente qui e può anche essere visualizzato.
Controllo LINQDataSource
È possibile UPDATE, INSERT e DELETEdati nelle pagine del sito Web ASP.NET con l'aiuto del controllo LINQDataSource. Non è assolutamente necessario specificare i comandi SQL poiché il controllo LINQDataSource utilizza comandi creati dinamicamente per tali operazioni.
Il controllo consente a un utente di utilizzare comodamente LINQ in una pagina Web ASP.NET mediante l'impostazione della proprietà nel testo del markup. LINQDataSource è molto simile a quello dei controlli comeSqlDataSource così come ObjectDataSourcein quanto può essere utilizzato per associare altri controlli ASP.NET presenti in una pagina a un'origine dati. Quindi, dobbiamo avere un filedatabase per spiegare le varie funzioni invocate dal controllo LINQDataSource.
Prima di iniziare la spiegazione dell'utilizzo del controllo nel modulo della pagina Web ASP.NET, è essenziale aprire la casella degli strumenti di Microsoft Visual Studio e trascinare il controllo LINQDataSource nella pagina .aspx del sito Web ASP.NET come nella figura seguente.
Il passaggio successivo consiste nel configurare LINQDataSource selezionando tutte le colonne per il record del dipendente.
Ora aggiungi un controllo GridView alla pagina .aspx e configuralo come mostrato nella figura seguente. Il controllo GridView è potente e offre flessibilità per lavorare con i dati. Subito dopo aver configurato il controllo, apparirà nel browser.
La codifica che può essere visualizzata ora sullo schermo per la pagina .aspx sarà:
<!DOCTYPE html>
<html>
<head runat = "server">
<title></title>
</head>
<body>
<form id = "form1" runat = "server">
<div>
<asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
DataKeyNames = "ContactID" DataSourceID = "LINQDataSource1">
<Columns>
<asp:BoundField DataField = "ContactID" HeaderText = "ContactID"
InsertVisible = "False" ReadOnly="True" SortExpression = "ContactID" />
<asp:CheckBoxField DataField = "NameStyle" HeaderText = "NameStyle"
SortExpression = "NameStyle" />
<asp:BoundField DataField = "Title" HeaderText = "Title" SortExpression = "Title" />
<asp:BoundField DataField = "FirstName" HeaderText = "FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField = "MiddleName" HeaderText = "MiddleName"
SortExpression = "MiddleName" />
<asp:BoundField DataField = "LastName" HeaderText = "LastName"
SortExpression = "LastName" />
<asp:BoundField DataField = "Suffix" HeaderText = "Suffix"
SortExpression = "Suffix" />
<asp:BoundField DataField = "EmailAddress" HeaderText = "EmailAddress"
SortExpression = "EmailAddress" />
</Columns>
</asp:GridView>
<br />
</div>
<asp:LINQDataSource ID = "LINQDataSource1" runat = "server"
ContextTypeName = "LINQWebApp1.AdventureWorksDataContext" EntityTypeName = ""
TableName = "Contacts">
</asp:LINQDataSource>
</form>
</body>
</html>
Qui va notato che è fondamentale impostare la proprietà ContextTypeName su quella della classe che rappresenta il database. Ad esempio, qui viene fornito come LINQWebApp1.AdventureWorksDataContext poiché questa azione stabilirà la connessione necessaria tra LINQDataSource e il database.
INSERIRE, AGGIORNARE e CANCELLARE i dati nella pagina ASP.NET utilizzando LINQ
Dopo aver completato rigorosamente tutti i passaggi precedenti, scegli il file LINQDataSource Tasks dal LINQDataSource Control e scegli tutte e tre le caselle per abilitare l'inserimento, abilitare l'aggiornamento e abilitare l'eliminazione dallo stesso, come mostrato nello screenshot seguente.
Presto il markup dichiarativo verrà visualizzato sullo schermo come il seguente.
<asp:LINQDataSource
ContextTypeName = "LINQWebApp1.AdventureWorksDataContext"
TableName = "Contacts"
EnableUpdate = "true"
EnableInsert = "true"
EnableDelete = "true"
ID = "LINQDataSource1"
runat = "server">
</asp:LINQDataSource>
Poiché sono presenti più righe e colonne, è preferibile aggiungere un altro controllo al modulo .aspx denominato Visualizzazione dettagli o Controllo principale sotto il controllo Visualizzazione griglia per visualizzare solo i dettagli di una riga selezionata della griglia. Scegliere le attività di visualizzazione dettagli dal controllo visualizzazione dettagli e selezionare le caselle di controllo come mostrato di seguito.
Ora, basta salvare le modifiche e premere Ctrl + F5 per visualizzare la pagina nel browser in cui è ora possibile eliminare, aggiornare, inserire qualsiasi record sul controllo della visualizzazione dei dettagli.