Sfruttare Javascript per eseguire query sul server tramite dynamic LINQ e l'interfaccia IQueryable

di Stefano Marchisio, in LINQ,

L'introduzione di ASP.NET MVC ha cambiato l'approccio che abbiamo nello sviluppare le nostre applicazioni. Se con ASP.NET WebForm facciamo largo uso dei postback, con i vantaggi e gli svantaggi che essi comportano, con ASP.NET MVC dobbiamo sviluppare le nostre applicazioni basandoci molto di più sul Javascript. Ciò inevitabilmente comporta che uno sviluppatore debba avere degli skill Javascript molto più elevati.

Per dimostrare quanto sia necessario avere una buona conoscenza del Javascript quando si usa ASP.NET MVC, supponiamo di dover creare una view al cui inteno c'è del codice Javascript che legge dei dati dal server per poi mostrarli paginati a video. Supponiamo inoltre di voler anche applicare dei filtri su tali dati.

Nel caso di un'applicazione che sfrutta ASP.NET WebForm, possiamo usare il controllo server UpdatePanel e in pochissimo tempo questa funzionalità è pronta.

Nel caso di un'applicazione che sfrutta ASP.NET MVC, dobbiamo eseguire una chiamata REST verso il server in modalità AJAX (nel proseguio dell'articolo verrà usato semplicemente il termine AJAX) e scrivere il codice per trasformare i dati ricevuti dal server (in formato json) in HTML. Per completare la funzionalità, sul server ci deve essere una action che restituisca i dati. Eseguire tutti questi passi comporta una notevole quantità di codice Javascript sul client e codice C# o Visual Basic sul server. Da questo esempio si evince chiaramente come la quantità di codice Javascript da scrivere con ASP.NET MVC sia notevole rispetto ad ASP.NET WebForm.

Ora facciamo un passo avanti: cosa potremmo fare se con ASP.NET MVC volessimo creare qualche cosa che ci permetta di creare la suddetta funzionalità in maniera più parametrizzata (magari avendo poi la possibilità di poter applicare dei template jquery sui dati che ci vengono restituiti)?

Per prima cosa pensiamo a come di filtrare i dati sul server. Un primo aiuto ci viene dall'interfaccia IQueryable. Con quest'interfaccia è possibile comporre delle query che vengono inviate al database nel momento in cui si enumera l'oggetto che rappresenta la query. Il problema è che i metodi dell'interfaccia IQueryable accettano come parametro delle lambda expression che, essendo tipizzate, rendono difficoltoso lavorare in modo generico come si potrebbe fare con delle semplici stringhe.

Per superare il problema della tipizzazione, esiste la libreria LINQ Dynamic Query Library (Dynamic LINQ d'ora in poi), rilasciata da Microsoft ma non inclusa nel .NET Framework, con la quale è possibile comporre delle query in modo dinamico. Infatti, i metodi di questa libreria invece di accettare in input una lambda expression, accettano delle stringhe che rappresentano la lambda expression. Saranno poi i metodi della libreria Dynamic LINQ a parsare le stringhe inserite e creare la lambda expression corrispondente. Questo meccanismo ci torna utile in quanto dal client possiamo generare una chiamata ajax contente al suo interno le stringhe che rappresentano la lambda expression che vogliamo eseguire sul server. Così facendo possiamo avere sul server un entry point con dei metodi che operano ad un alto livello di astrazione. Sarà poi la logica contenuta nei metodi sul server ad intrerpretare la chiamata ajax in arrivo al fine di creare la query corrispondente (in modo da non dover creare un metodo adhoc per ogni chiamata). L'unica cosa che resta da fare è scrivere il codice javascript che crea la chiamata ajax contenente le lambda expression, in formato stringa compatibile con ciò che ci sarà nell'action sul server.

Sintetizzando l'introduzione fatta fino ad ora, quello che vogliamo realizzare è scrivere in Javascript una query parametrica, usando il formalismo di LINQ, che ci dia la possibilita di personalizzare la query la generata sul server e di poter poi mostrare i dati ricevuti all'interno di un template jquery per la renderizzazione HTML. Un esempio del codice Javascript che vogliamo scrivere è visibile nel seguente snippet.

var text1 = $("#text1").val();
  var text2 = $("#text2").val();
  context.beginWhere("and");
  if (text1!= "") {
    context.addWhereClause(   "City"     , "=", text1);
  }      
  if (text2 != "") {
    context.addWhereClause("Country", "=", text2);
  }

  var r = context.endWhere();            
  context.from("/Grid1/GetDataJson").where(r.value,r.param).orderBy(
    "CustomerID").pagingWithSize(10).applyTempClient("template1");

Questo articolo si basa su un progetto esistente e liberamente scaricabile all'indirizzo http://javascriptiqueryable.codeplex.com/. Il codice che abbiamo appena visto sfrutta questo progetto. Prima di proseguire con la spiegazione di ciò che è stato realizzato, vediamo prima in dettaglio quali sono gli scopi del progetti e quali tecnologie sono state utilizzate.

Scopi del progetto e tecnologie utilizzate

Il progetto che è stato realizzato ha i seguenti requisiti:

  • Poter effettuare delle query che utilizzano una sintassi linq
  • Poter effettuare delle query che non utilizzano una sintassi linq
  • Avere delle funzionalità per la paginazione
  • Ottenere un risultato in formato json da manipolare poi sul client
  • Ottenere un risultato in formato html da manipolare poi sul client
  • Per i due punti precedenti avere la possibilità di impostare dei template (client o server)
  • Utilizzare una sintassi fluent.

A questo punto definiamo le tecnologie utilizzate lato client e lato server:

  • Lato client: jQuery e i plugin per applicare i template per renderizzare HTML
  • Lato server: MVC3.

Il seguito di questo articolo sarà suddiviso in tre sezioni in cui verrà spiegato come realizzare in termini pratici quello che fino ad ora è stato espresso in termini teorici. La prima sezione si occupa di mostrare i contratti tra client e server, la seconda sezione mostra il codice Javascript mentre la terza sezione mostra il codice server. Partiamo ora con il parlare del contratto tra client e server.

4 pagine in totale: 1 2 3 4
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti