Recentemente ho scritto alcuni post in inglese nel mio blog su LINQ:
Purtroppo non ho tempo di scrivere tutto in due lingue, per questo segnalo a chi usa LINQ di dare un'occhiata a questi post, in particolare all'ultimo (Distinct e OrderBy) che rischia di far perdere molto tempo perché può far pensare a un bug della libreria, quando in realtà (come direbbe Microsoft con una frase un po' irritante) si tratta di un comportamento "by design".
Buona lettura.
A PDC 2008 verrà presentata la nuova versione di C#, che sarà appunto la 4.0. Al momento non sono disponibili specifiche o dettagli tecnici, ma questa intervista al team che progetta il linguaggio, guidato da Anders Hejlsberg, anticipa le considerazioni e le linee guida che sono state adottate per arrivare alla nuova versione.
Tra i temi trattati: programmazione funzionale, linguaggi dinamici (e C# resterà un linguaggio statico) e soprattutto programmazione concorrente. Ricordiamoci che C# 4.0 sarà rilasciato nel 2009/2010, verrà usato per scrivere i programmi che saranno rilasciati nel 2011/2012 e per allora un desktop con 4 o 8 core sarà qualcosa di assolutamente normale, mentre sui server parleremo di core usando 2 o 3 cifre.
Ripeto, non ci sono dettagli e il webcast dura 50 minuti - non si impara nulla, ma è una conversazione interessante da vedere in qualche ritaglio di tempo.
Un commento al mio post precedente su ADO.NET Entity Framework contiene la domanda fatidica: che fine farà LINQ to SQL? E implicitamente ne contiene un'altra altrettanto importante: quando usare LINQ to SQL?
Andiamo con ordine: LINQ to SQL sarà supportato per almeno 10 anni. Fa parte di .NET Framework 3.5, la sua interfaccia pubblica sarà mantenuta anche nelle prossime versioni di .NET Framework. Difficile che facciano marcia indietro su questo, almeno nel breve. Ma sicuramente potrebbero cambiarne l'implementazione. Questo è un argomento molto più complesso che però non siamo in grado di analizzare almeno fino a che non vedremo (a PDC 2008?) quali sono i piani per .NET 4.0. Nella peggiore delle ipotesi, non evolverà dallo stato attuale.
Ciò detto, veniamo alla seconda domanda, che non può non tenere conto delle considerazioni precedenti. Premetto che quello che segue è una mia personale opinione e non rappresenta una posizione espressa da Microsoft in alcuna sede, ufficiale e non.
LINQ to SQL va bene in molti scenari che mi trovo ad affrontare con una certa frequenza. Raggruppati per categorie:
- Procedure batch di trasformazione/elaborazione di dati.
- Tipicamente sono fatte apposta per un database (SQL Server nel nostro caso) e sono scritte in C# perché con T-SQL o SSIS non si avrebbe a disposizione uno strumento adeguato
- Esempi: algoritmi di valorizzazione del magazzino; procedura di import formati custom (binari o ascii con strutture variabili); ...
- Semplici interfacce di manutenzione di un database (es. a scopo amministrativo, edit tabelle di configurazione et simili)
- Accesso a database locali (es. per contenere dati di configurazione)
Probabilmente ve ne sono altre, ma è importante sottolineare quello che manca e che oggi non scrivere usando LINQ to SQL:
- Applicazioni enterprise e/o n-Tier (salvo usare LINQ to SQL per alcune parti del DAL, ma la cosa richiederebbe una lunga discussione)
- Framework per sviluppo ERP
- Implementazioni ERP - insomma il classico "gestionale"
I motivi per non usarlo in questi casi sono sia implementativi (prestazioni, architettura, ecc.) che strategici (supporto nel lungo periodo, evoluzione in versioni future, ecc.). Mentre i motivi per usarlo nei casi che ho esposto in precedenza sono riassumibili in una parola: produttività.
Ho usato LINQ to SQL in alcuni casi dove ho potuto confrontare il risultato ottenuto con la realizzazione corrispondente senza LINQ to SQL. Semplicemente, aumenta la produttività. Si scrive meno codice, quello che c'è è più leggibile e non si perde troppo in prestazioni (a meno che non dobbiate scrivere molti dati - purtroppo non c'è un supporto diretto al bulk insert e bisogna ricorrere ad ADO.NET). Qualche preoccupazione in più per la gestione degli errori, problematica che però negli scenari che ho descritto è di solito meno critica.
Un aspetto determinante nell'usare LINQ to SQL negli scenari che ho descritto è la facilità di deployment. Se c'è .NET 3.5, c'è tutto quello che serve. Non ci sono altre DLL o altri componenti da installare. Sarà banale, ma su applicazioni con poche centinaia di righe di codice il fatto di dover installare delle librerie aggiuntive su dei server (penso ai batch notturni) può diventare un problema peggiore dei vantaggi dati dall'uso di LINQ to SQL.
Sarei felice di avere dei feedback a queste considerazioni, soprattutto se avete già iniziato a usare LINQ to SQL.
Un argomento caldo in questi giorni è il futuro di ADO.NET Entity Framework. Durante TechEd Developers a Orlando si è parlato molto di ADO.NET Entity Framework, molto meno di LINQ to SQL (che ora non è più in carico al team di C# ma a quello di ADO.NET, che è lo stesso che sviluppa Entity Framework - ma questo sarebbe oggetto di un altro discorso che farò quando capirò anche io i piani che hanno realmente). Per molti aspetti, Entity Framework è un ORM molto giovane, ma è fatto da Microsoft, e questo di per sé ne garantirà un uso diffuso.
A causa delle limitazioni esistenti in questa prima versione, è nata una "mozione di sfiducia" (non so come tradurla diversamente) firmata da poco meno di 300 persone (a oggi). Ad ogni modo, non sono numeri così piccoli. Tim Mallalieu ha risposto a queste critiche e il team di Entity Framework ha inaugurato un blog dedicato alla progettazione e sviluppo della versione 2.0 di Entity Framework.
Personalmente, pur non essendo un forte sostenitore di questa tecnologia, credo di comprendere quale sia il problema di fondo. Alcuni (ma forse molti) considerano ADO.NET Entity Framework come un tool di ORM da comparare con tool simili, come NHibernate. Per Microsoft, non è solo questo. Uno dei punti chiave nella visione di Microsoft è che Entity Framework sia un layer di astrazione sul modello dei dati utilizzabile non solo da programmi scritti in C#/VB/ecc., ma anche da tool di reportistica che rappresentano il modello di entità direttamente all'utente finale che vuole realizzare i suoi report. Io non sono così convinto che sia possibile avere un approccio simile nel 100% dei casi, ma devo ammettere che in molte situazioni questa possibilità è adeguata alle esigenze. Nutro forti dubbi sul fatto che possano amalgamare anche i modelli multidimensionali all'interno di Entity Framework (è una cosa che hanno annunciato di voler fare, anche se a oggi non c'è alcuna traccia di feature che vadano in questa direzione) e il rischio latente è che questa visione "universale" porti a fare scelte nell'adozione di questa tecnologia basate sull'attesa di funzionalità future, che chissà se e quando arriveranno.
Ciò detto, ripeto, il fatto di poter supportare un ambiente di reportistica direttamente da Entity Framework giustifica, in effetti, la necessità di avere un proprio linguaggio di interrogazione (Entity SQL) che non sarebbe necessario usando LINQ to Entities. Il vero problema è decidere se e quando usare questa tecnologia. Oggi come oggi, io sarei cauto e inizierei qualche sperimentazione (soprattutto in scenari dove si può sfruttare la capacità di essere un layer di astrazione superiore e non solo un ORM), senza però fare già scelte definitive. In fondo, è (ancora per poco) un prodotto in Beta.
PS: Forse sta passando di moda il politically correct. Un post che riprende il tema della mozione di sfiducia è questo di Dinesh Kulkarni, a suo tempo (ma ora non più) coinvolto nello sviluppo di LINQ to SQL. Dissacrante e divertente, basta essere disposti a fare un po' di auto-ironia.
Sono finalmente disponibili due capitoli di esempio del libro Programming Microsoft LINQ che abbiamo scritto io e Paolo Pialorsi. Di seguito un breve estratto dei contenuti; i link alle pagine di download sono nel titolo dei capitoli. A seguire un elenco di tutti i capitoli inclusi nel libro.
Chapter 6 - Tools for LINQ to SQL
In this chapter, we took a look at the tools that are available to generate LINQ to SQL entities and DataContext classes. The .NET Framework SDK includes the command-line tool named SQLMetal. Visual Studio 2008 has a graphical editor known as the Object Relational Designer. Both allow the creation of a DBML file, the generation of source code in C# and Visual Basic, and the creation of an external XML mapping file. The Object Relational Designer also allows you to edit an existing DBML file, dynamically importing existing tables, views, stored procedures, and user-defined functions from an existing SQL Server database.
Chapter 16 - LINQ and ASP.NET
This chapter showed you how to leverage the new features and controls available in ASP.NET 3.5 to develop data-enabled Web applications, using LINQ to SQL and LINQ in general. Consider that what you have seen is really useful for rapidly defining Web site prototypes and simple Web solutions. On the other hand, in enterprise-level solutions you will probably need at least one intermediate layer between the ASP.NET presentation layer and the data persistence one, represented by LINQ to SQL. In real enterprise solutions, you usually also need a business layer that abstracts all business logic, security policies, and validation rules from any kind of specific persistence layer. And you will probably have a Model-View-Controller or Model-View-Presenter pattern governing the UI. In this more complex scenario, chances are that the LinqDataSource control will be tied to entities collections more often than to LINQ to SQL results.
Programming Microsoft LINQ
- Part I LINQ FOUNDATIONS
- 1 LINQ Introduction
- 2 LINQ Syntax Fundamentals
- 3 LINQ to Objects
- Part II LINQ to Relational Data
- 4 LINQ to SQL: Querying Data
- 5 LINQ to SQL: Managing Data
- 6 Tools for LINQ to SQL
- 7 LINQ to DataSet
- 8 LINQ to Entities
- Part III LINQ and XML
- 9 LINQ to XML: Managing the XML Infoset
- 10 LINQ to XML: Querying Nodes
- Part IV Advanced LINQ
- 11 Inside Expression Trees
- 12 Extending LINQ
- 13 Parallel LINQ
- 14 Other LINQ Implementations
- Part V Applied LINQ
- 15 LINQ in a Multitier Solution
- 16 LINQ and ASP.NET
- 17 LINQ and WPF/Silverlight
- 18 LINQ and the Windows Communication Foundation
- Appendixes
- A ADO.NET Entity Framework
- B C# 3.0: New Language Features
- C Visual Basic 2008: New Language Features
Io e Paolo siamo stati intervistati a TechEd in merito a cosa significa scrivere un libro come Programming LINQ.
Oggi il video è visibile direttamente sul portale di TechEd Online, ma non sarà ancora per molto in prima pagina... se siete curiosi di sentire i nostri errori in inglese, potete vedere il video in bassa risoluzione o in alta risoluzione. Buona visione!
Ieri e oggi ho avuto modo di valutare le caratteristiche di un prodotto/servizio di Microsoft che sicuramente interesserà molte aziende in Italia (e non solo). Si tratta di Microsoft Software Licensing and Protection Services e fondamentalmente fa due cose:
1. Protegge il codice (meglio, una parte del codice) dal reverse engineering
2. Gestisce il licensing
Per quanto riguarda la protezione del codice, il meccanismo è questo: si scelgono una o più funzioni del proprio codice, che vengono convertite da codice IL a codice SVML (Secure Virtual Machine Language). Il codice SVML è eseguibile solo all’interno di una SVM (Secure Virtual Machine) che è specifico per ogni azienda che produce software. In pratica, se la software house A distribuisce del codice, distribuisce anche una SVM che sarà diversa da una software house diversa (B). Il codice SVML è crittografato usando un algoritmo che è decifrabile solo dalla SVM specifica della propria azienda. Una differenza rispetto a IL è che il codice non è compilato dal jitter ma viene sostanzialmente interpretato all’interno della SVM. Di fatto, questo rende tale codice ancora più sicuro di una compilazione in codice managed. Ma ogni cosa ha un prezzo, e qui il prezzo sono le prestazioni, certamente inferiori a quelle del codice IL compilato dal jitter e poi eseguito come codice nativo. Questo rende improponibile proteggere in questo modo tutto il codice di un’applicazione, ma un algoritmo critico (come proprietà intellettuale) che non ha troppe implicazioni prestazionali è certamente un buon candidato per questo servizio.
L’altro servizio offerto è il licensing: la SVM lega il suo funzionamento al controllo di attivazione remoto che consente di controllare le licenze attivate, fornire versioni a tempo, controllare le singole funzioni attive, ecc. ecc.
Costi: al momento chi è ha un abbonamento MSDN ha la versione Evaluation a disposizione e per andare in produzione c’è un costo annuale di gestione (che non ricordo) più 1 dollaro ad attivazione ma... attenzione! Dal 28 luglio 2008 ci saranno significative modifiche. Questo vuol dire che conviene in ogni caso aspettare qualche settimana perché a dire delle persone di Microsoft con cui ho parlato il cambiamento sarà molto importante.
Per saperne di più (in italiano) potete leggere questo esauriente post di Silvano Coriani sull’argomento.
Appena finita DevCon 2008 io e Paolo siamo partiti alla volta di Orlando per TechEd 2008 Developers, dove siamo venuti principalmente per raccogliere i feedback sul libro Programming Microsoft LINQ che è appena uscito.
Prima di tutto, un po' di feedback da DevCon: la conferenza ci sembra sia andata bene, dobbiamo ancora esaminare in dettaglio i feedback ma l'impressione è stata buona, anche perché la partecipazione è stata alta anche nelle sessioni che finivano verso le 18.30. Un'impressione che ho avuto è stata quella di un'orientamento verso LINQ to Entities a scapito di LINQ to SQL, nonostante sia un prodotto in Beta (anche se ancora per poco). Uno degli obiettivi che abbiamo a TechEd è anche di capire che aria tira: da molti fattori (blog, agenda e altro ancora...) sembra che LINQ to SQL possa lasciare il passo a LINQ to Entities, ma un conto è ciò che fa Microsoft, un conto ciò che fa il mercato. Se l'adozione di LINQ to SQL sarà significativa, diventerà difficile abbandonarlo senza un percorso di convergenza verso LINQ to Entities (che ne consenta un uso, diciamo così, più ottimizzato ma anche semplificato verso SQL Server, più o meno com'è adesso). Se invece l'adozione sarà scarsa... allora potrebbe anche diventare supportato ma senza avere evoluzioni, di fatto condannandolo a un oblio precoce. Credo sia troppo presto per trarre conclusioni e quando emergerà qualche dato interessante tornerò sicuramente a parlarne.
Visto che parliamo di TechEd... non ci sono grosse novità in vista, l'agenda che ho appena finito di rivedere copre tecnologie rilasciate o in fase di imminente rilascio (come SQL 2008 e Visual Studio 2008 SP1 con relativo .NET 3.5 SP1). Al di là delle molte sessioni su ADO.NET Entity Framework (alcune delle quali anche piuttosto sovrapposte come argomenti, a prima vista), mi ha colpito un certo numero di sessioni apparentemente "fumose" che forse servono a preparare il terreno per PDC 2008. L'unica cosa "strana" è il fatto che tutte le sessioni relative a Microsoft AX 2009 sono segnate in agenda senza descrizione e senza speaker. Aspetteranno la keynote di Bill Gates?
A proposito di Bill Gates: questa sarà l'ultima keynote "importante" della sua carriera, per lo meno di fronte a una platea di sviluppatori. Alla prossima PDC, infatti, non farà più ombra a Ray Ozzie, Chief Software Architect di Microsoft. Ma per PDC ci vuole ancora qualche mese, per i suoi effetti anche qualche anno, quindi per ora affrontiamo il presente.
Nei prossimi giorni vi consiglio di dare un'occhiata ai blog sul sito di Programming LINQ perché specialmente sull'argomento LINQ sarà più probabile che interverremo direttamente lì. Sicuramente tra una settimana faremo comunque un riepilogo su quanto visto qua a Orlando.
Il libro Programming Microsoft LINQ è finalmente disponibile. Abbiamo anche aggiornato il sito web di supporto (http://programminglinq.com), dove è possibile scaricare il codice di esempio del libro.
Cosa c’è nel libro? Abbiamo provato a coprire tutto quello che è incluso nella RTM, ma abbiamo anche introdotto tecnologie ancora in beta o in CTP ancora embrionali, come LINQ to Entities e Parallel LINQ. Al fondo di questo post trovate un elenco dei capitoli per avere un’idea del contenuto del libro.
Martedì comincia DevCon 2008, dove LINQ sarà uno degli argomenti caldi. La settimana successiva saremo a Orlando per partecipare anche a qualche attività legata al lancio del libro durante TechEd Developers 2008. Non sono previsti annunci di rilievo, ma questa sarà probabilmente l’ultima keynote di Bill Gates (martedì 3 giugno, nel pomeriggio per l’Italia) e quindi è lecito attendersi qualche novità. Vedremo...
Programming Microsoft LINQ
- Part I LINQ FOUNDATIONS
- 1 - LINQ Introduction
- 2 - LINQ Syntax Fundamentals
- 3 - LINQ to Objects
- Part II LINQ to Relational Data
- 4 - LINQ to SQL: Querying Data
- 5 - LINQ to SQL: Managing Data
- 6 - Tools for LINQ to SQL
- 7 - LINQ to DataSet
- 8 - LINQ to Entities
- Part III LINQ and XML
- 9 - LINQ to XML: Managing the XML Infoset
- 10 - LINQ to XML: Querying Nodes
- Part IV Advanced LINQ
- 11 - Inside Expression Trees
- 12 - Extending LINQ
- 13 - Parallel LINQ
- 14 - Other LINQ Implementations
- Part V Applied LINQ
- 15 - LINQ in a Multitier Solution
- 16 - LINQ and ASP.NET
- 17 - LINQ and WPF/Silverlight
- 18 - LINQ and the Windows Communication Foundation
- Appendixes
- A - ADO.NET Entity Framework
- B - C# 3.0: New Language Features
- C - Visual Basic 2008: New Language Features
Non sono completamente d'accordo con Joel Spolsky ma... ma... in questo articolo c'è un fondo di verità. E siccome si tratta di un post veramente divertente... beh, non perdetevelo! L'argomento è se gli obiettivi strategici di Microsoft (e di Google, ma l'obiettivo è più Microsoft) siano rivolti verso qualcosa che non è un'esigenza di nessuno. Live Mesh è solo l'ennesimo servizio per sincronizzare i file? Si tratta dell'ennesimo progetto sponsorizzato da chi scrive software perché lo ritiene ingegneristicamente interessante?
Se la discussione vi sembra interessante... sotto con i commenti.
Per un motivo che non saprei nemmeno spiegare, mi sono appena imbattuto in un albero genealogico dei linguaggi piuttosto aggiornato. Pur non essendo completo, è interessante vedere come nel tempo percorsi apparentemente incompatibili abbiano cominciato a "fondersi" (programmazione funzionale e a oggetti).
Per avere altri link si può andare alla pagina che contiene il diagramma che ho visto, con molti link a diagrammi analoghi. Ripassare (o studiare) un po' di storia non fa mai male e aiuta a vedere le cose in prospettiva diversa, perché uno ripensa a tutti i linguaggi che ha usato e che magari oggi non saprebbe più usare (lo dico anche a titolo personale!).
Posto non molto tecnico, pur parlando di tecnologia.
Primo argomento, i Robot. Microsoft ha organizzato una competizione chiamata RoboChamps (già solo il sito in Silverlight vale la pena) che consente a chi usa Microsoft Robotics Developer Studio di far esercitare il "suo" robot in un'arena dove l'obiettivo non è distruggere tutto, ma più semplicemente uscire da un labirinto, fare un sistema di guida automatica, passeggiare su Marte e raccogliere dati da mandare sulla Terra, salvare persone intrappolate dopo un terremoto e vincere una gara di Sumo tra robot. Certo, alla fine il torneo è una competizione che porterà il codice dal simulatore al mondo reale (robot veri!) e il gran finale con robot reali sarà a PDC 2008. Ah, già, quest'anno a fine ottobre ci sarà la PDC, la conferenza dove vengono di solito annunciate le novità più importanti dei prossimi anni per gli sviluppatori che lavorano con tecnologie Microsoft. La competizione servirà a indorare la pillola?
Leggendo alcuni articoli (tecnici e non) su Mesh ho percepito l'idea dei giornalisti che Microsoft stava "finalmente" puntando a un modello non più basato su Windows. In realtà, sarebbe più corretto dire "non più basato solo sul desktop". Per capire la differenza date un'occhiata a questa demo che spiega meglio di molte parole cosa si può fare con Mesh. Purtroppo la beta non è ancora disponibile a tutti, comunque l'idea mi sembra molto più evolutiva (dal punto di vista di Windows) che non rivoluzionaria. Chiaramente è ancora presto per fare commenti e predire come sarà adottata questa tecnologia, però in un certo senso è come se piano piano si realizzassero cose che si erano immaginate già parecchi anni fa (in particolare da quando si cominciò a parlare di Web Services). Per inciso, guardando questa demo ho scoperto Channel 10: una manna se volete perdervi in demo e preview varie... come questo post su Microsoft Surface che punta a una prova reale (non una demo fatta su un palco).
La settimana scorsa ho avuto l'opportunità di presentare alla European PASS Conference 2008 il mio lavoro sulle relazioni molti-a-molti tra dimensioni in Analysis Services e la possibilità di usarle per scopi "non convenzionali" nella modellazione multidimensionale. Chiaramente, in una conferenza su SQL Server, questo non era l'argomento più "caldo" e ciò di cui mi sono trovato a parlare spesso con partecipanti e speaker riguardava direttamente o indirettamente LINQ.
Purtroppo, alcune delle preoccupazioni che io e Paolo condividevamo prima di scrivere due libri sull'argomento si stanno rivelando reali. Due "problemi" vengono percepiti da chi vede LINQ per la prima volta (relativamente a persone che hanno a fare con i database, questo va chiarito). Primo, LINQ viene associato a LINQ to SQL. Secondo, "se il codice SQL non lo posso controllare, che fine fanno le prestazioni"?
Devo dirlo, comincio a preoccuparmi per il fatto che, se questa sarà la percezione di LINQ, essa creerà problemi nella diffusione e soprattutto nel corretto uso di LINQ. Per cominciare, non credo che LINQ to SQL sia l'implementazione più importante di LINQ. Ciò che ritengo importante è l'approccio a un modello di programmazione più dichiarativa che contestualmente semplifica il modo con cui i dati vengono trattati all'interno di un programma. Se ci si concentra su una singola implementazione significa che si trascura l'aspetto pervasivo di LINQ rispetto alle diverse fonti dati che si possono gestire. Dal mio punto di vista, LINQ to Objects è l'implementazione più importante di LINQ - il rischio è che la si consideri invece un accessorio privo di reale importanza, mentre è da lì che si dovrebbe partire.
Per quanto riguarda l'aspetto prestazionale, è evidente che ciò dipende da molteplici fattori ma ancora una volta c'è un errore di percezione. Il fatto che esista uno strumento non significa che lo si debba usare. Se ho un'automobile in garage, posso anche prenderla per andare a comprare il giornale all'edicola distante 300 metri, ma ci sono altri mezzi di trasporto più efficienti (anche in termini di tempo, oltre che di costi e consumi). Assumere che a priori si debba sempre usare lo stesso strumento indipendentemente dal lavoro che va effettuato è un errore. Molte applicazioni possono trarre vantaggio da LINQ to SQL. In molte altre, non avrebbe senso utilizzarlo. E' più ragionevole parlare di confronto tra LINQ to SQL e prodotti di ORM come NHibernate, perché pur essendo implementazioni molto diverse tra loro, per lo meno il terreno di confronto è simile.
Ragionerò ancora molto su queste cose preparando le sessioni per DevCon 2008. Se qualcuno vuole contribuire alla discussione, i commenti sono aperti.
Segnalo che è stata rilasciato il Visual C++ 2008 Feature Pack, della cui beta avevo parlato a gennaio. Un post contenente alcuni link interessanti per scoprire cosa c'è a disposizione è questo di Jason Zander.
Se qualcuno mantiene ancora applicazioni in MFC, sarei felice di ricevere feedback su questa release (potete usare i commenti al post).
Ho da poco cominciato a usare LINQPad e devo dire che è un tool molto utile. Si può usare per provare query LINQ in maniera interattiva. Se si usa LINQ to SQL, LINQPad genera automaticamente la classe DataContext necessaria e fornise un ambiente di esecuzione delle proprie query.
Al momento si sente la mancanza di qualcosa simile a IntelliSense, ma una prossima versione di LINQPad dovrebbe includere una funzione di AutoComplete. Consiglio di provare questo tool a tutti quelli che vogliono studiare LINQ e a quelli che, pur conoscendolo, vogliono avere un ambiente in cui sia molto semplice sviluppare e provare le proprie query LINQ.
More Posts
Next page »