{"id":25868,"date":"2020-11-25T00:00:00","date_gmt":"2020-11-24T23:00:00","guid":{"rendered":"https:\/\/blexin.com\/?p=25868"},"modified":"2021-01-13T09:39:55","modified_gmt":"2021-01-13T08:39:55","slug":"linq-in-depth-aspetti-avanzati","status":"publish","type":"post","link":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/","title":{"rendered":"LINQ in depth: aspetti avanzati"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"25871\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/attachment\/image00\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image00\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-25871\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Nel&nbsp;<a href=\"https:\/\/www.blexin.com\/it-IT\/Article\/Blog\/LINQ-un-linguaggio-per-domarli-tutti-88\" target=\"_blank\" rel=\"noreferrer noopener\">precedente articolo<\/a>, abbiamo dato uno sguardo all\u2019evoluzione del linguaggio C# e delle novit\u00e0 in esso introdotte a supporto di LINQ, iniziando a scoprire le principali caratteristiche di quest\u2019ultimo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Proseguiamo ora, osservando alcune&nbsp;peculiarit\u00e0 delle due sintassi che LINQ ci mette a disposizione e che, come abbiamo detto, sono praticamente equivalenti.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Method syntax\nvar filteredCustomersAge = customers.Where(c =&gt; c.Age &gt; 19 &amp;&amp; c.Age &lt; 36);\n \n\/\/ Query syntax\nvar filteredCustomersAge =\n    from customer in customers\n    where customer.Age &gt; 19 &amp;&amp; customer.Age &lt; 36\n    select customer;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Nella precedente query inerente la Query Syntax, l&#8217;operatore di query&nbsp;<em>where<\/em>&nbsp;in fase di compilazione viene convertito con la chiamata al metodo di estensione&nbsp;<em>.Where()<\/em>&nbsp;utilizzato nell\u2019esempio di codice scritto con la Method Syntax.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Alcune query tuttavia devono essere effettuate con la Method Syntax.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ad esempio, per esprimere una query che recupera il numero di elementi che corrispondono ad una condizione specificata:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar filteredCustomersAgeCount = customers\n    .Where(c =&gt; c.Age &gt;19 &amp;&amp; c.Age &lt;36)\n    .Count();                                \/\/Count: 2\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">O per una query che recupera l&#8217;elemento con il valore massimo in una sequenza di origine:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar customerWithOlderAge = customers.Select(c =&gt; c.Age).Max();   \/\/Age: 55\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Tuttavia, \u00e8 sempre possibile applicare la sintassi del metodo dopo aver utilizzato la sintassi delle query come nel prossimo esempio, dove useremo la Query Syntax per recuperare le et\u00e0 dei clienti &gt; 19 e &lt; di 36 anni e, utilizzando la Method Syntax, prenderemo poi l\u2019et\u00e0 pi\u00f9 alta:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nint maxAgeInRange = \n   (from customer in customers\n    where customer.Age &gt; 19 &amp;&amp; customer.Age &lt; 36\n    select customer.Age).Max();\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Vediamo invece qualche esempio dove \u00e8 pi\u00f9 comodo utilizzare la Query Syntax.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Grazie all\u2019utilizzo della keyword&nbsp;<em>let<\/em>, possiamo immagazzinare un risultato e utilizzarlo all\u2019interno della query. Supponiamo di avere un metodo GetYearsOfFidelity() che ci restituisce gli anni di affiliazione di un cliente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar querySyntaxGoldenCustomers =\n    from customer in customers\n    let yearsOfFidelity = GetYearsOfFidelity(customer)\n    where yearsOfFidelity &gt; 5\n    orderby yearsOfFidelity\n    select customer.CustomerName;\n \nvar methodSyntaxGoldenCustomers = customers\n    .Select(customer =&gt; new   \/\/anonymous type\n    {\n        YearsOfFidelity = GetYearsOfFidelity(customer),\n        Name = customer.CustomerName\n    })\n    .Where(x =&gt; x.YearsOfFidelity &gt; 5)\n    .OrderBy(x =&gt; x.YearsOfFidelity)\n    .Select(x =&gt; x.Name);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Come vediamo, con la sintassi della query il risultato \u00e8 pi\u00f9 chiaro. La sintassi del metodo richiede di creare un&nbsp;<em>anonymous type<\/em>&nbsp;e utilizzarlo per il resto della query.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se avessimo pi\u00f9 origini dati, la sintassi della query sarebbe probabilmente la scelta migliore, perch\u00e9 possiamo utilizzare la parola chiave&nbsp;<em>from&nbsp;<\/em>pi\u00f9 volte, rendendo il codice pi\u00f9 esplicativo:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar rows = Enumerable.Range(1, 3); \/\/1,2,3\nvar columns = new string&#x5B;] { &quot;A&quot;, &quot;B&quot;, &quot;C&quot; };\n \nvar querySyntax = from row in rows\n                  from col in columns\n                  select $&quot;cell &#x5B;{row}, {col}]&quot;;\n \nvar methodSyntax = rows.SelectMany(row =&gt; columns, (r, c) =&gt; $&quot;cell &#x5B;{r}, {c}]&quot;);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Prendiamo ora in esame del codice che integra la funzionalit\u00e0 degli&nbsp;<em>Object Initializer<\/em>&nbsp;con LINQ. Gli&nbsp;<em>Object Initializer<\/em>&nbsp;vengono usati in genere nelle espressioni di query, quando proiettano i dati di origine in un nuovo tipo di dati. Utilizziamo sempre la nostra classe Customer e supponiamo di avere un&#8217;origine dati denominata IncomingOrders e che per ogni ordine con OrderSize maggiore di 100 si debba creare un nuovo oggetto Customer basato sull&#8217;ordine:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar largeOrderCustomers = from o in IncomingOrders\n                          where o.OrderSize &gt; 100\n                          select new Customer { CustomerName = o.CName, CustomerID = o.CId };\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">L&#8217;origine dati pu\u00f2 avere diverse propriet\u00e0 rispetto alla classe Customer, ad esempio OrderSize, ma utilizzando l\u2019<em>Object Initializer<\/em>&nbsp;i dati restituiti dalla query vengono modellati nel tipo di dati desiderato con una singola operazione. Di conseguenza, \u00e8 ora disponibile un oggetto IEnumerable che contiene i nuovi oggetti Customer desiderati.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In questo e nel precedente&nbsp;articolo su LINQ, abbiamo parlato delle feature a supporto di questo potente framework e visto piccoli esempi del suo utilizzo. Ma come mai abbiamo parlato di&nbsp;<em>delegate anonimi<\/em>?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Analizziamo una delle query viste in precedenza:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar filteredCustomersAge = customers.Where(c =&gt; c.Age &gt; 19 &amp;&amp; c.Age &lt; 36);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Il metodo&nbsp;<em>Where&nbsp;<\/em>prende come parametro una condizione, in questo caso espressa da una&nbsp;<em>lambda expression<\/em>, che \u00e8 una funzione che prende in ingresso un oggetto Customer e restituisce un booleano:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nFunc&lt;Customer, bool&gt; func = c =&gt; c.Age &gt; 19 &amp;&amp; c.Age &lt; 36;\n \nvar filteredCustomersAge = customers.Where(func);\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Ma cos\u2019\u00e8 in effetti quella funzione?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"896\" height=\"84\" data-attachment-id=\"25887\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/attachment\/image01-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/11\/image01-1.png?fit=896%2C84&amp;ssl=1\" data-orig-size=\"896,84\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image01\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/11\/image01-1.png?fit=896%2C84&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/11\/image01-1.png?resize=896%2C84&#038;ssl=1\" alt=\"\" class=\"wp-image-25887\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/11\/image01-1.png 896w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/11\/image01-1-480x45.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 896px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Quella funzione \u00e8 un&nbsp;<em>delegate<\/em>! Una variabile che fa riferimento a codice eseguibile non elaborato. Gli&nbsp;<em>extension methods<\/em>&nbsp;LINQ di IEnumerable&lt;T&gt; accettano come parametro un&nbsp;<em>delegate<\/em>, sia che si tratti di&nbsp;<em>delegate anonimi<\/em>&nbsp;come nel caso precedente con la&nbsp;<em>lambda expression<\/em>, o di metodi definiti esplicitamente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nbool func(Customer customer)\n   {\n       return customer.Age &gt; 19 &amp;&amp; customer.Age &lt; 36;\n   }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In teoria, \u00e8 possibile analizzare l&#8217;IL per capire che cosa il metodo che stiamo utilizzando sta tentando di fare e applicare la logica di quel metodo a qualsiasi origine dati sottostante. Ma questo non sarebbe un lavoro semplice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fortunatamente .NET ci fornisce l&#8217;interfaccia IQueryable&lt;T&gt; che ci procura&nbsp;gli stessi metodi di estensione dell&#8217;interfaccia dalla quale deriva, ovvero IEnumerable&lt;T&gt;. Tali metodi per\u00f2, accettano come parametro gli&nbsp;<em>expression tree<\/em>&nbsp;al posto dei&nbsp;<em>delegate<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diamo giusto uno sguardo a cos\u2019\u00e8 e a come si traduce il codice trovato in un&#8217;espressione in un&nbsp;<em>expression tree.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per comodit\u00e0, prendiamo in esame una semplice&nbsp;<em>lambda expression<\/em>&nbsp;simile alla precedente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nFunc&lt;int, int, int&gt; function = (a,b) =&gt; a + b;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">LINQ ci fornisce una semplice sintassi, il primo passo \u00e8 aggiungere un&#8217;istruzione using per introdurre lo spazio dei nomi Linq.Expressions:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing System.Linq.Expressions;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Ora possiamo creare un&nbsp;<em>expression tree<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nExpression&lt;Func&lt;int, int, int&gt;&gt; expression = (a, b) =&gt; a + b;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">La&nbsp;<em>lambda expression<\/em>&nbsp;viene convertita in un&nbsp;<em>expression tree<\/em>&nbsp;di tipo Expression&lt;T&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">che non \u00e8 un codice eseguibile: tutti gli elementi della nostra espressione vengono rappresentati come nodi di una struttura di dati.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Possiamo visualizzare la struttura in debug con Visual Studio:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"180\" data-attachment-id=\"25894\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/attachment\/image02-3\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02.png?fit=913%2C180&amp;ssl=1\" data-orig-size=\"913,180\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image02\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02.png?fit=913%2C180&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02.png?resize=913%2C180&#038;ssl=1\" alt=\"\" class=\"wp-image-25894\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image02.png 913w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-480x95.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 913px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019<em>expression tree&nbsp;<\/em>\u00e8 composto da quattro propriet\u00e0 principali:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>Body<\/em>: contiene il corpo dell&#8217;espressione e le sue informazioni.<\/li><li><em>Parameters<\/em>: contiene informazioni sui parametri dell&#8217;espressione lambda.<\/li><li><em>NodeType&nbsp;<\/em>: contiene informazioni sui diversi tipi possibili di nodi di espressione, come quelli che restituiscono costanti, quelli che restituiscono parametri, quelli che decidono se un valore \u00e8 inferiore a un altro (&lt;), quelli che decidono se uno \u00e8 maggiore di un altro (&gt;), quelli che aggiungono valori insieme (+), ecc.<\/li><li><em>Type<\/em>: ottiene il tipo statico dell&#8217;espressione. In questo caso, l&#8217;espressione \u00e8 di tipo<br>Func &lt; int , int , int &gt;.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Abbiamo quindi la possibilit\u00e0 di utilizzare ed analizzare queste propriet\u00e0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ora che abbiamo le idee pi\u00f9 chiare, analizziamo il codice di questa query LINQ, nello specifico LINQ to SQL:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar query = from c in db.Customers\n                    where c.City == &quot;Nantes&quot;\n                    select new { c.City, c.CompanyName };\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">La variabile&nbsp;<em>query&nbsp;<\/em>restituita da questa espressione LINQ \u00e8 di tipo&nbsp;<em>IQueryable<\/em>, che contiene nella sua definizione una propriet\u00e0 di tipo&nbsp;<em>Expression<\/em>. La propriet\u00e0 di tipo&nbsp;<em>Expression&nbsp;<\/em>\u00e8progettata per contenere l\u2019<em>expression tree&nbsp;<\/em>associato a un\u2019istanza di IQueryable ed \u00e8 una struttura di dati equivalente al codice eseguibile trovato in un&#8217;espressione di query:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IQueryable : IEnumerable\n{\n    Type ElementType { get; }\n    Expression Expression { get; }\n    IQueryProvider Provider { get; }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Ma qual \u00e8 il motivo principale per cui, in alcuni casi, per esempio con LINQ to SQL, abbiamo bisogno dell\u2019interfaccia&nbsp;<em>IQueryable<\/em>&nbsp;e degli&nbsp;<em>expression tree<\/em>?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una query LINQ to SQL non viene effettivamente eseguita all&#8217;interno del programma C#!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il codice di una espressione di query viene tradotto in una query SQL che pu\u00f2 essere inviata a un altro processo come stringa. In questo caso, un database di SQL Server. Ovviamente \u00e8 molto pi\u00f9 semplice tradurre una struttura di dati come un&nbsp;<em>expression tree<\/em>, piuttosto che tradurre l\u2019IL o codice eseguibile non elaborato in istruzioni SQL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La query precedente viene quindi prima tradotta in una istruzione SQL come quella seguente e poi eseguita su un server:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nSELECT &#x5B;t0].&#x5B;City], &#x5B;t0].&#x5B;CompanyName]\nFROM &#x5B;dbo].&#x5B;Customers] AS &#x5B;t0]\nWHERE &#x5B;t0].&#x5B;City] = @p0\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Un algoritmo molto sofisticato di LINQ to SQL analizza le diverse parti di un&nbsp;<em>expression tree&nbsp;<\/em>e ne ricava una stringa contenente un\u2019istruzione SQL che restituir\u00e0 i dati richiesti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diamo uno sguardo anche alla definizione dell\u2019interfaccia IEnumerable&lt;T&gt;:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IEnumerable&lt;T&gt; : IEnumerable\n{\n    IEnumerator&lt;T&gt; GetEnumerator();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Come possiamo vedere, non contiene un campo di tipo Expression.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ecco perch\u00e9 l\u2019interfaccia IEnumerable&lt;T&gt; \u00e8 pi\u00f9 adatta in contesti dove si pu\u00f2 convertire l&#8217;espressione della query direttamente nel codice .NET che pu\u00f2 essere eseguito e dove non \u00e8 necessario tradurlo in una stringa o eseguire qualsiasi altra operazione complessa su di essa. Viene quindi utilizzata per eseguire query su dati provenienti da raccolte in-memory come List e Array, ed \u00e8 pi\u00f9 adatta&nbsp;per le query LINQ to Object e LINQ to XML.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Non supporta il&nbsp;<em>lazy loading<\/em>&nbsp;e non \u00e8 quindi adatta a scenari dove abbiamo bisogno di paginazione.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inoltre durante una query di dati da un database, IEnumerable esegue una query di selezione sul lato server, carica i dati in memoria sul lato client e quindi filtra i dati.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019interfaccia IQueryable&lt;T&gt; invece, come abbiamo visto viene utilizzata dove \u00e8 necessario tradurre un&#8217;espressione di query in una stringa che verr\u00e0 passata a un altro processo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c8 quindi migliore per eseguire query sui dati da raccolte out-memory come database remoti e servizi, e con LINQ to SQL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Infine, supporta il&nbsp;<em>lazy loading<\/em>&nbsp;per gli scenari dove c\u2019\u00e8 bisogno di paginazione e supporta query personalizzate utilizzando i metodi CreateQuery ed Execute.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In questo articolo ci siamo soffermati ad analizzare alcuni aspetti del funzionamento di LINQ e delle funzionalit\u00e0 a suo supporto. Ci vorrebbe davvero molto tempo per spiegare quello che c\u2019\u00e8 dietro e tutto quello che un framework cos\u00ec complesso ci permette di fare.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Terminerei, per\u00f2, elencando alcuni dei vantaggi che possiamo ottenere utilizzandolo:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Ci permette di scrivere meno codice, in modo pi\u00f9 leggibile e manutenibile e di ridurre i tempi di sviluppo.<\/li><li>Non dobbiamo imparare un nuovo linguaggio di query per ogni tipo di origine dati o formato dati.<\/li><li>Ci fornisce il supporto IntelliSense per la scrittura delle query sulle raccolte generiche e maggior sicurezza grazie al controllo del tipo degli oggetti in fase di compilazione.<\/li><li>Ci permette di eseguire query in modo pi\u00f9 semplice anche da pi\u00f9 sorgenti di dati in una singola query e grazie alla sua funzionalit\u00e0 gerarchica, ci consente di comporre query unendo pi\u00f9 tabelle in meno tempo.<\/li><li>Semplifica il debug grazie alla sua integrazione col linguaggio C#.<\/li><li>Ci offre un modo facile per convertire un tipo di dato in un altro, come la trasformazione di dati SQL in dati XML.<\/li><li>Pu\u00f2 essere esteso, il che significa che \u00e8 possibile utilizzare LINQ per eseguire query su nuovi tipi di origine dati.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Al prossimo articolo! Stay Tuned!<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Continuiamo ad analizzare come LINQ abbia rivoluzionato il modo con cui accediamo ai dati in .NET<\/p>\n","protected":false},"author":196716244,"featured_media":25871,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637374],"tags":[688637382,688637383],"class_list":["post-25868","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-c","tag-linq"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>LINQ in depth: aspetti avanzati - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"LINQ in depth: aspetti avanzati - Blexin\" \/>\n<meta property=\"og:description\" content=\"Continuiamo ad analizzare come LINQ abbia rivoluzionato il modo con cui accediamo ai dati in .NET\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-24T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-13T08:39:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Francesco Vastarella\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francesco Vastarella\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/\"},\"author\":{\"name\":\"Francesco Vastarella\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\"},\"headline\":\"LINQ in depth: aspetti avanzati\",\"datePublished\":\"2020-11-24T23:00:00+00:00\",\"dateModified\":\"2021-01-13T08:39:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/\"},\"wordCount\":1516,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"C#\",\"Linq\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/\",\"name\":\"LINQ in depth: aspetti avanzati - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2020-11-24T23:00:00+00:00\",\"dateModified\":\"2021-01-13T08:39:55+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/linq-in-depth-aspetti-avanzati\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"LINQ in depth: aspetti avanzati\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\",\"name\":\"Francesco Vastarella\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"caption\":\"Francesco Vastarella\"},\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/author\\\/francesco-vastarellablexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"LINQ in depth: aspetti avanzati - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/","og_locale":"it_IT","og_type":"article","og_title":"LINQ in depth: aspetti avanzati - Blexin","og_description":"Continuiamo ad analizzare come LINQ abbia rivoluzionato il modo con cui accediamo ai dati in .NET","og_url":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/","og_site_name":"Blexin","article_published_time":"2020-11-24T23:00:00+00:00","article_modified_time":"2021-01-13T08:39:55+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Francesco Vastarella","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Francesco Vastarella","Tempo di lettura stimato":"9 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/"},"author":{"name":"Francesco Vastarella","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d"},"headline":"LINQ in depth: aspetti avanzati","datePublished":"2020-11-24T23:00:00+00:00","dateModified":"2021-01-13T08:39:55+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/"},"wordCount":1516,"image":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","keywords":["C#","Linq"],"articleSection":["Blog"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/","url":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/","name":"LINQ in depth: aspetti avanzati - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","datePublished":"2020-11-24T23:00:00+00:00","dateModified":"2021-01-13T08:39:55+00:00","author":{"@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d"},"breadcrumb":{"@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/it\/blog\/linq-in-depth-aspetti-avanzati\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/it\/"},{"@type":"ListItem","position":2,"name":"LINQ in depth: aspetti avanzati"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/it\/#website","url":"https:\/\/blexin.com\/it\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d","name":"Francesco Vastarella","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","caption":"Francesco Vastarella"},"url":"https:\/\/blexin.com\/it\/author\/francesco-vastarellablexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-6Je","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/25868","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/users\/196716244"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/comments?post=25868"}],"version-history":[{"count":25,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/25868\/revisions"}],"predecessor-version":[{"id":27632,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/25868\/revisions\/27632"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media\/25871"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media?parent=25868"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/categories?post=25868"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/tags?post=25868"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}