SlideShare ist ein Scribd-Unternehmen logo
1 von 25
TorinoTechnologiesGroup



             Javascript to IQueryable
http://www.linqitalia.com/ricerca/super.aspx?action=author&key=Stefano+Marchisio
                    http://Javascriptiqueryable.codeplex.com


          www.TorinoTechnologiesGroup.it
Stefano Marchisio            http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

              JavaScript e’ bello/brutto ???
                     ( e’ come il vino: bere con moderazione !!!)

   Esistono situazioni in cui siamo “costretti” ad utilizzare in linguaggio Javascript in
   alcuni parti delle nostre applicazioni.

                                1) PhoneGap applications
                                2) MVC / Web applications

                  Che ci piaccia o no ... In alcuni casi dobbiamo usarlo !!!

                Windows 8 ? – Se uno conosce XAML e C# meglio evitarlo

              Pertanto dobbiamo prendere confidenza con questo “signore”



Stefano Marchisio                     http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




  L'introduzione di MVC ha cambiato l'approccio che abbiamo nello sviluppare le
  nostre applicazioni; infatti se con le "webform" si fa largo uso dei "postback" (con i
  vantaggi e gli svantaggi che essi comportano), con MVC non abbiamo piu' i
  "postback" per cui dobbiamo sviluppare le nostre applicazioni dando un maggior
  peso alla porzione di codice javascript presente nelle nostre pagine.




Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

  Una delle problematiche piu' comuni che si deve affrontare e' visualizzare una view
  MVC al cui inteno c'e' del codice javascript che legge dei dati dal server in formato
  "json" per poi paginarli (eventualmente applicando dei filtri su tali dati).

  Infatti e' necessario:
  1) Creare una chiamata rest in modalita' ajax.
  2) Sul server ci deve essere un “action method“ che elabori la richiesta.
  3) Il browser deve elaborare la risposta.

   Cio’ comporta la scrittura di una certa dose di codice (da entrambe le parti) spesso
   ripetitiva. Come fare a non dover reinventare la ruota tutte le volte ?

   Magari avendo la possibilita’ di poter effettuare delle query dinamiche ?



Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

   Iqueryable e’ potente, purtroppo accetta come parametro solo delle “lambda
   expression” che per loro natura sono tipizzate per cui risulta difficoltoso poter
   lavorare in modo dinamico (senza dover ricorrere ad ODATA).

                 Come risolvere il problema ?
               Siamo disposti a portare Iqueryable nel Controller ? Se si ...


   Anche se non e' inclusa nel framework esiste una libreria scritta da Microsoft
   "Dynamic Expressions and Queries in LINQ" con la quale e' possibile comporre delle
   query in modo dinamico; infatti invece di usare le "lambda expression" all'interno
   delle varie clausole (where, orderby e select) vengono usate della stringhe.



Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

      Dynamic Expressions and Queries in LINQ
            var query = db.Customers.
            Where("City = @0 and Orders.Count >= @1", "London", 10).
            OrderBy("CompanyName").
            Select("new(CompanyName as Name, Phone)");


   Saranno poi i metodi di "Dynamic Expressions and Queries in LINQ" che parsando
   le stringhe inserite creano l' "expression tree" corrispondente.


                      Dynamic Expressions.html


Stefano Marchisio                http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup



                         Requisiti del progetto
1) Poter effettuare delle query in cui linq e’ abilitato lato client (reqmessage).
2) Poter effettuare delle query in cui linq non e’ abilitato lato client (querystring).
3) Avere delle funzionalita' per la paginazione.
4) Ottenere un risultato in formato dati json da manipolare poi sul client.
5) Ottenere un risultato in formato dati html da manipolare poi sul client.
6) Per i 2 punti precedenti avere la possibilita' di impostare dei template (client o server)
7) Il tutto utilizzando una sintassi "metodo punto metodo" tipo jquery.




Stefano Marchisio                     http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




   (*) L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso
   impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter
   comporre localmente la query

Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




                            Demo




Stefano Marchisio          http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

   Contratti request (linq abilitato/linq non abilitato)
   var reqmessage = {
    "groupresult": value,
    "enablepaging": value,
    "where":{"value": "", "param": "", ptype: "" },
    "order":{"value": "", "param": ""},
    "select":{"value":"", "param": ""},
    "skip": n,
    "take": n
   } a

  url?currpage=n&currsize=n&param1=valore2&param2=valore2"&orderby=value

   N.B. Nel caso linq non sia abilitato verra’ creato un url contente solo dei
   parametri, le varie clausole di select, where e orderby verranno create poi sul
   server.


Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

 Contratti response (comuni linq abilitato/linq non abilitato)
                                 var resmessage = {
                                   "total": n,
                                   "records": n,
                                   "rows":[{},{}, ... ,{}]
                                 }


N.B. Il server puo' restituire sia dati grezzi che testo in formato html.

1) Se sono restituiti dati grezzi la proprieta' rows conterra’ un array di dati in formato “json“

2) Se sono restituiti dati testo in formato html la proprieta' rows (non sara' piu' un array)
conterra' tali dati.



Stefano Marchisio                       http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup
    Riepilogando, a fronte dei 2 contratti utilizzati per le richieste (e di cio' che ci puo'
    restiture il server json/html) esistono sostanzialmente 4 tipi di richieste e 2 tipi di
    risposte.

      1) context.linqEnabled = true;
      context.from("/Grid1/GetDataJson").where(" ... slide/succ ...").orderBy(
                  "CustomerID").skip(3).take(6).applyTempClient();

      2) context.linqEnabled = true;
      context.from("/Grid1/GetDataJson").where(" ... slide/succ ...").orderBy(
              "CustomerID").pagingWithSize(10).applyTempClient();

    N.B. In entrambi i casi linq e' abilitato lato client (context.linqEnabled = true;)

 GetDataJson?message={"groupresult":false,"enablepaging":true,"select":{"value":"","par
 am":""},"order":{"value":"CustomerID","param":null},"where":{"value":"Country=@0","
 param":["spain"],"ptype":["str"]},"skip":0,"take":10}


Stefano Marchisio                      http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup
                           Where clause/1
   var index = 0; var where = "";
   var param = new Array();
   if (text1!= "") {
      if (where != "")
         where = where + " and City = @" + index;
      else where = where + " City = @" + index ;
      param[index] = text1; index++;
   }
   if (text2 != "") {
      if (where != "")
         where = where + " and Country = @" + index;
      else where = where + " Country = @" + index;
      param[index] = text2; index++;
   }
   context.from("/Grid1/GetDataJson").where(where,param).orderBy("CustomerID").
                       pagingWithSize(10).applyTempClient();


Stefano Marchisio                http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

                          Where clause/2

      context.beginWhere("and");
      if (text1!= "") {
         context.addWhereClauseStr( "City" , "=", text1);
         //context.addWhereClause( "City" , "=", text1);
      }
      if (text2 != "") {
         context.addWhereClauseStr("Country", "=", text2);
         //context.addWhereClause("Country", "=", text2);
      }
      var r = context.endWhere();
      context.from("/Grid1/GetDataJson").where(r.value,r.param,r.ptype).orderBy(
                 "CustomerID").pagingWithSize(10).applyTempClient();




Stefano Marchisio                http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup


     3) context.linqEnabled = false;
     context.from("/Grid3/GetDataJson"). where(swhere). orderBy(
            “CustomerID") .skip(3).take(6).applyTempClient();

     4) context.linqEnabled = false;
     context.from("/Grid3/GetDataJson"). where(swhere).OrderBy(
         “CustomerID") PagingWithSize(10).applyTempClient();


   N.B. In entrambi i casi linq non e' abilitato lato client (context.linqEnabled = false;)

  “/GetDataJson?pagecurr=n&pagesize=n&p1=valore2&p2=valore2&orderby=value “

 La substringa “p1=valore2&p2=valore2” e’ passata tramite il metodo “where(swhere)”



Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup



   Tra i requisiti iniziali abbiamo detto che si possono ottenere sia dati in formato
   “json” che dati in formato testo “html”. L’ una o l’ altra opzione e’ gestita tramite il
   metodo con cui si copleta la query lato client.




              applyTempClient (“x")/applyTempServer(“x")




Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




   (*) L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso
   impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter
   comporre localmente la query

Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup


   Esistono 2 tipi di richieste che possono arrivare sul server (linq abilitato/linq non
   abilitato) per cui parametro presente sull'action method del controller e'
   rappresentato da 2 oggetti distinti “RequestLinq” e “RequestRest”. Entrambe le
   richieste devono invocare i metodi che effettuano la query, i quali necessitato che
   venga passato come parametro l'oggetto presente sull'action method. Onde evitare
   una duplicazione del codice sottostante ho creato un interfaccia "IRequestQuery"
   che   viene   usata   per   invocare    l'   "extension   method"    di   IQueryable
   "JQuery(IRequestQuery)", che contiene la logica per lavorare con gli "expression
   tree" al fine di poter comporre la nostra query. Inoltre tale interfaccia viene anche
   implementata da "RequestLinq" e " RequestRest".




Stefano Marchisio                   http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup



 Visto che gli oggetti "RequestLinq" e " RequestRest" devono essere instanziati e popolati
 con cio' che e' presente sull'url, e non andando bene il "ModelBinder" di default, ho
 creato 2 ModelBinder custom: "ModelBinderLinqRequest" e "ModelBinderRestRequest"
 (che mappano tali oggetti). In questo modo a fronte dei 2 tipi di richieste che possono
 giungere sul server, sara' il ModelBinder custom associato al tipo di richiesta che mi crea
 e configura il parametro dell'action method. Lavorando poi con un'interfaccia comune
 "IRequestQuery" faccio in modo che cio' che c'e' sotto non sia influenzato dai 2 contesti
 diversi di esecuzione.




Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup


   Il metodo     "JQuery(IRequestQuery)” e’ un extension method dell’ interfaccia
   IQueryable ed accetta come parametro oggetti di tipo (RequestLinq/RequestRest).
   Ritorna un oggetto managed con il seguente formato (la proprieta’ data contiene un
   array di dati grezzi):


                               result = new
                                {
                                   total = total,
                                   records = count,
                                   rows = data,
                                };




Stefano Marchisio                  http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

   1) Link abilitato lato client e solo template lato client

   public ActionResult GetDataJson(RequestLinq linq)
   {
      var query = Repository.GetRepository<Customer>().Query();
      return Json(query.JQuery(linq), JsonRequestBehavior.AllowGet);
    }

   2) Link abilitato lato client e template lato client o lato server

   public ActionResult GetDataJson(RequestLinq linq)
   {
      var query = Repository.GetRepository<Customer>().Query();
      object data = this.TryApplyView(linq, query.JQuery(linq));
      return Json(data, JsonRequestBehavior.AllowGet);
   }



Stefano Marchisio                  http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup

   Nel caso venga applicato un template lato server (una partialview) devo far
   ritornare solo il relativo contenuto html. Per far questo ci viene in aiuto l' "extension
   method" della classe "Controller“.

                 this.TryApplyView(par, query.JQuery(par))

   Ritorna un oggetto managed con il seguente formato (la proprieta’ data contiene
   un array di dati grezzi oppure testo html):


                                result = new
                                 {
                                    total = total,
                                    records = count,
                                    rows = data,
                                 };


Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




   L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso
   impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter
   comporre localmente la query e fare quello che viene fatto nel browser per le query
   in cui c'e' linq abilitato lato client. Cio’ mi permette di usufruire dell’interfaccia
   comune IRequestQuery.




Stefano Marchisio                    http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup



   3) Link non abilitato lato client e template lato client o lato server

   public ActionResult GetDataJson(RequestRest rest)
   {
     rest.Operator = WhereOperator.And;
     rest.AddWhereMapping( "City“ , "=", "campo1");
     rest.AddWhereMapping("Country", "=", "campo2");
     rest.DefaultOrderBy("CustomerID");
     var query = Repository.GetRepository<Customer>().Query();
     object result = this.TryApplyView(rest, query.JQuery(rest));
     return Json(result, JsonRequestBehavior.AllowGet);
   }




Stefano Marchisio                  http://Javascriptiqueryable.codeplex.com
TorinoTechnologiesGroup




                            Demo




Stefano Marchisio          http://Javascriptiqueryable.codeplex.com

Weitere ähnliche Inhalte

Ähnlich wie How create a single page apps using html5 and javascript

E suap - tecnologie client
E suap - tecnologie client E suap - tecnologie client
E suap - tecnologie client Sabino Labarile
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBStefano Dindo
 
Introduzione a jQuery
Introduzione a jQueryIntroduzione a jQuery
Introduzione a jQuerySandro Marcon
 
Techbar nodejs+mongodb+mongoose
Techbar nodejs+mongodb+mongooseTechbar nodejs+mongodb+mongoose
Techbar nodejs+mongodb+mongooseMassimo Biagioli
 
Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini Whymca
 
SVILUPPO DI SERVIZI REST PER ANDROID
SVILUPPO DI SERVIZI REST PER ANDROIDSVILUPPO DI SERVIZI REST PER ANDROID
SVILUPPO DI SERVIZI REST PER ANDROIDLuca Masini
 
AngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webAngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webLuca Milan
 
.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNetMauro Servienti
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009Massimiliano Dessì
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meetingguest67beeb9
 
SmartClient by Isomorphic - Rich internet applications
SmartClient by Isomorphic - Rich internet applicationsSmartClient by Isomorphic - Rich internet applications
SmartClient by Isomorphic - Rich internet applicationsClaudio Bosticco
 
Spring, IBatis e Transazioni Aop Nel Jug Avis Web
Spring, IBatis e Transazioni Aop Nel Jug Avis WebSpring, IBatis e Transazioni Aop Nel Jug Avis Web
Spring, IBatis e Transazioni Aop Nel Jug Avis WebMassimiliano Dessì
 
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo MicrosoftAsp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo MicrosoftStefano Benedetti
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.jsMichele Capra
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8Valerio Radice
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Railsjekil
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con ScalaFranco Lombardo
 

Ähnlich wie How create a single page apps using html5 and javascript (20)

Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
E suap - tecnologie client
E suap - tecnologie client E suap - tecnologie client
E suap - tecnologie client
 
Novità di Asp.Net 4.0
Novità di Asp.Net 4.0Novità di Asp.Net 4.0
Novità di Asp.Net 4.0
 
MongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDBMongoDB User Group Padova - Overviews iniziale su MongoDB
MongoDB User Group Padova - Overviews iniziale su MongoDB
 
Introduzione a jQuery
Introduzione a jQueryIntroduzione a jQuery
Introduzione a jQuery
 
Techbar nodejs+mongodb+mongoose
Techbar nodejs+mongodb+mongooseTechbar nodejs+mongodb+mongoose
Techbar nodejs+mongodb+mongoose
 
Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini
 
SVILUPPO DI SERVIZI REST PER ANDROID
SVILUPPO DI SERVIZI REST PER ANDROIDSVILUPPO DI SERVIZI REST PER ANDROID
SVILUPPO DI SERVIZI REST PER ANDROID
 
AngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni webAngularJS – Reinventare le applicazioni web
AngularJS – Reinventare le applicazioni web
 
.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meeting
 
SmartClient by Isomorphic - Rich internet applications
SmartClient by Isomorphic - Rich internet applicationsSmartClient by Isomorphic - Rich internet applications
SmartClient by Isomorphic - Rich internet applications
 
Spring, IBatis e Transazioni Aop Nel Jug Avis Web
Spring, IBatis e Transazioni Aop Nel Jug Avis WebSpring, IBatis e Transazioni Aop Nel Jug Avis Web
Spring, IBatis e Transazioni Aop Nel Jug Avis Web
 
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo MicrosoftAsp.Net MVC 3 - Il Model View Controller secondo Microsoft
Asp.Net MVC 3 - Il Model View Controller secondo Microsoft
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Rails
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 

How create a single page apps using html5 and javascript

  • 1. TorinoTechnologiesGroup Javascript to IQueryable http://www.linqitalia.com/ricerca/super.aspx?action=author&key=Stefano+Marchisio http://Javascriptiqueryable.codeplex.com www.TorinoTechnologiesGroup.it Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 2. TorinoTechnologiesGroup JavaScript e’ bello/brutto ??? ( e’ come il vino: bere con moderazione !!!) Esistono situazioni in cui siamo “costretti” ad utilizzare in linguaggio Javascript in alcuni parti delle nostre applicazioni. 1) PhoneGap applications 2) MVC / Web applications Che ci piaccia o no ... In alcuni casi dobbiamo usarlo !!! Windows 8 ? – Se uno conosce XAML e C# meglio evitarlo Pertanto dobbiamo prendere confidenza con questo “signore” Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 3. TorinoTechnologiesGroup L'introduzione di MVC ha cambiato l'approccio che abbiamo nello sviluppare le nostre applicazioni; infatti se con le "webform" si fa largo uso dei "postback" (con i vantaggi e gli svantaggi che essi comportano), con MVC non abbiamo piu' i "postback" per cui dobbiamo sviluppare le nostre applicazioni dando un maggior peso alla porzione di codice javascript presente nelle nostre pagine. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 4. TorinoTechnologiesGroup Una delle problematiche piu' comuni che si deve affrontare e' visualizzare una view MVC al cui inteno c'e' del codice javascript che legge dei dati dal server in formato "json" per poi paginarli (eventualmente applicando dei filtri su tali dati). Infatti e' necessario: 1) Creare una chiamata rest in modalita' ajax. 2) Sul server ci deve essere un “action method“ che elabori la richiesta. 3) Il browser deve elaborare la risposta. Cio’ comporta la scrittura di una certa dose di codice (da entrambe le parti) spesso ripetitiva. Come fare a non dover reinventare la ruota tutte le volte ? Magari avendo la possibilita’ di poter effettuare delle query dinamiche ? Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 5. TorinoTechnologiesGroup Iqueryable e’ potente, purtroppo accetta come parametro solo delle “lambda expression” che per loro natura sono tipizzate per cui risulta difficoltoso poter lavorare in modo dinamico (senza dover ricorrere ad ODATA). Come risolvere il problema ? Siamo disposti a portare Iqueryable nel Controller ? Se si ... Anche se non e' inclusa nel framework esiste una libreria scritta da Microsoft "Dynamic Expressions and Queries in LINQ" con la quale e' possibile comporre delle query in modo dinamico; infatti invece di usare le "lambda expression" all'interno delle varie clausole (where, orderby e select) vengono usate della stringhe. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 6. TorinoTechnologiesGroup Dynamic Expressions and Queries in LINQ var query = db.Customers. Where("City = @0 and Orders.Count >= @1", "London", 10). OrderBy("CompanyName"). Select("new(CompanyName as Name, Phone)"); Saranno poi i metodi di "Dynamic Expressions and Queries in LINQ" che parsando le stringhe inserite creano l' "expression tree" corrispondente. Dynamic Expressions.html Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 7. TorinoTechnologiesGroup Requisiti del progetto 1) Poter effettuare delle query in cui linq e’ abilitato lato client (reqmessage). 2) Poter effettuare delle query in cui linq non e’ abilitato lato client (querystring). 3) Avere delle funzionalita' per la paginazione. 4) Ottenere un risultato in formato dati json da manipolare poi sul client. 5) Ottenere un risultato in formato dati html da manipolare poi sul client. 6) Per i 2 punti precedenti avere la possibilita' di impostare dei template (client o server) 7) Il tutto utilizzando una sintassi "metodo punto metodo" tipo jquery. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 8. TorinoTechnologiesGroup (*) L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter comporre localmente la query Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 9. TorinoTechnologiesGroup Demo Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 10. TorinoTechnologiesGroup Contratti request (linq abilitato/linq non abilitato) var reqmessage = { "groupresult": value, "enablepaging": value, "where":{"value": "", "param": "", ptype: "" }, "order":{"value": "", "param": ""}, "select":{"value":"", "param": ""}, "skip": n, "take": n } a url?currpage=n&currsize=n&param1=valore2&param2=valore2"&orderby=value N.B. Nel caso linq non sia abilitato verra’ creato un url contente solo dei parametri, le varie clausole di select, where e orderby verranno create poi sul server. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 11. TorinoTechnologiesGroup Contratti response (comuni linq abilitato/linq non abilitato) var resmessage = { "total": n, "records": n, "rows":[{},{}, ... ,{}] } N.B. Il server puo' restituire sia dati grezzi che testo in formato html. 1) Se sono restituiti dati grezzi la proprieta' rows conterra’ un array di dati in formato “json“ 2) Se sono restituiti dati testo in formato html la proprieta' rows (non sara' piu' un array) conterra' tali dati. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 12. TorinoTechnologiesGroup Riepilogando, a fronte dei 2 contratti utilizzati per le richieste (e di cio' che ci puo' restiture il server json/html) esistono sostanzialmente 4 tipi di richieste e 2 tipi di risposte. 1) context.linqEnabled = true; context.from("/Grid1/GetDataJson").where(" ... slide/succ ...").orderBy( "CustomerID").skip(3).take(6).applyTempClient(); 2) context.linqEnabled = true; context.from("/Grid1/GetDataJson").where(" ... slide/succ ...").orderBy( "CustomerID").pagingWithSize(10).applyTempClient(); N.B. In entrambi i casi linq e' abilitato lato client (context.linqEnabled = true;) GetDataJson?message={"groupresult":false,"enablepaging":true,"select":{"value":"","par am":""},"order":{"value":"CustomerID","param":null},"where":{"value":"Country=@0"," param":["spain"],"ptype":["str"]},"skip":0,"take":10} Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 13. TorinoTechnologiesGroup Where clause/1 var index = 0; var where = ""; var param = new Array(); if (text1!= "") { if (where != "") where = where + " and City = @" + index; else where = where + " City = @" + index ; param[index] = text1; index++; } if (text2 != "") { if (where != "") where = where + " and Country = @" + index; else where = where + " Country = @" + index; param[index] = text2; index++; } context.from("/Grid1/GetDataJson").where(where,param).orderBy("CustomerID"). pagingWithSize(10).applyTempClient(); Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 14. TorinoTechnologiesGroup Where clause/2 context.beginWhere("and"); if (text1!= "") { context.addWhereClauseStr( "City" , "=", text1); //context.addWhereClause( "City" , "=", text1); } if (text2 != "") { context.addWhereClauseStr("Country", "=", text2); //context.addWhereClause("Country", "=", text2); } var r = context.endWhere(); context.from("/Grid1/GetDataJson").where(r.value,r.param,r.ptype).orderBy( "CustomerID").pagingWithSize(10).applyTempClient(); Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 15. TorinoTechnologiesGroup 3) context.linqEnabled = false; context.from("/Grid3/GetDataJson"). where(swhere). orderBy( “CustomerID") .skip(3).take(6).applyTempClient(); 4) context.linqEnabled = false; context.from("/Grid3/GetDataJson"). where(swhere).OrderBy( “CustomerID") PagingWithSize(10).applyTempClient(); N.B. In entrambi i casi linq non e' abilitato lato client (context.linqEnabled = false;) “/GetDataJson?pagecurr=n&pagesize=n&p1=valore2&p2=valore2&orderby=value “ La substringa “p1=valore2&p2=valore2” e’ passata tramite il metodo “where(swhere)” Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 16. TorinoTechnologiesGroup Tra i requisiti iniziali abbiamo detto che si possono ottenere sia dati in formato “json” che dati in formato testo “html”. L’ una o l’ altra opzione e’ gestita tramite il metodo con cui si copleta la query lato client. applyTempClient (“x")/applyTempServer(“x") Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 17. TorinoTechnologiesGroup (*) L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter comporre localmente la query Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 18. TorinoTechnologiesGroup Esistono 2 tipi di richieste che possono arrivare sul server (linq abilitato/linq non abilitato) per cui parametro presente sull'action method del controller e' rappresentato da 2 oggetti distinti “RequestLinq” e “RequestRest”. Entrambe le richieste devono invocare i metodi che effettuano la query, i quali necessitato che venga passato come parametro l'oggetto presente sull'action method. Onde evitare una duplicazione del codice sottostante ho creato un interfaccia "IRequestQuery" che viene usata per invocare l' "extension method" di IQueryable "JQuery(IRequestQuery)", che contiene la logica per lavorare con gli "expression tree" al fine di poter comporre la nostra query. Inoltre tale interfaccia viene anche implementata da "RequestLinq" e " RequestRest". Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 19. TorinoTechnologiesGroup Visto che gli oggetti "RequestLinq" e " RequestRest" devono essere instanziati e popolati con cio' che e' presente sull'url, e non andando bene il "ModelBinder" di default, ho creato 2 ModelBinder custom: "ModelBinderLinqRequest" e "ModelBinderRestRequest" (che mappano tali oggetti). In questo modo a fronte dei 2 tipi di richieste che possono giungere sul server, sara' il ModelBinder custom associato al tipo di richiesta che mi crea e configura il parametro dell'action method. Lavorando poi con un'interfaccia comune "IRequestQuery" faccio in modo che cio' che c'e' sotto non sia influenzato dai 2 contesti diversi di esecuzione. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 20. TorinoTechnologiesGroup Il metodo "JQuery(IRequestQuery)” e’ un extension method dell’ interfaccia IQueryable ed accetta come parametro oggetti di tipo (RequestLinq/RequestRest). Ritorna un oggetto managed con il seguente formato (la proprieta’ data contiene un array di dati grezzi): result = new { total = total, records = count, rows = data, }; Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 21. TorinoTechnologiesGroup 1) Link abilitato lato client e solo template lato client public ActionResult GetDataJson(RequestLinq linq) { var query = Repository.GetRepository<Customer>().Query(); return Json(query.JQuery(linq), JsonRequestBehavior.AllowGet); } 2) Link abilitato lato client e template lato client o lato server public ActionResult GetDataJson(RequestLinq linq) { var query = Repository.GetRepository<Customer>().Query(); object data = this.TryApplyView(linq, query.JQuery(linq)); return Json(data, JsonRequestBehavior.AllowGet); } Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 22. TorinoTechnologiesGroup Nel caso venga applicato un template lato server (una partialview) devo far ritornare solo il relativo contenuto html. Per far questo ci viene in aiuto l' "extension method" della classe "Controller“. this.TryApplyView(par, query.JQuery(par)) Ritorna un oggetto managed con il seguente formato (la proprieta’ data contiene un array di dati grezzi oppure testo html): result = new { total = total, records = count, rows = data, }; Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 23. TorinoTechnologiesGroup L’ oggetto RequestRest ha una serie di proprieta'/metodi tramite i quali posso impostare un mapping tra i parametri dell'url ed i campi dell ' entity al fine di poter comporre localmente la query e fare quello che viene fatto nel browser per le query in cui c'e' linq abilitato lato client. Cio’ mi permette di usufruire dell’interfaccia comune IRequestQuery. Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 24. TorinoTechnologiesGroup 3) Link non abilitato lato client e template lato client o lato server public ActionResult GetDataJson(RequestRest rest) { rest.Operator = WhereOperator.And; rest.AddWhereMapping( "City“ , "=", "campo1"); rest.AddWhereMapping("Country", "=", "campo2"); rest.DefaultOrderBy("CustomerID"); var query = Repository.GetRepository<Customer>().Query(); object result = this.TryApplyView(rest, query.JQuery(rest)); return Json(result, JsonRequestBehavior.AllowGet); } Stefano Marchisio http://Javascriptiqueryable.codeplex.com
  • 25. TorinoTechnologiesGroup Demo Stefano Marchisio http://Javascriptiqueryable.codeplex.com