Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/Default.aspx it-IT Daniele Mantovani Subtext Version 2.6.0.0 Daniele Mantovani http://blogs.ugidotnet.org/images/RSS2Image.gif http://blogs.ugidotnet.org/dmantovani/Default.aspx 77 60 Workshop UGISS ad Alessandria http://blogs.ugidotnet.org/dmantovani/archive/2010/01/16/97869.aspx <p>Oggi ad Alessandria si è svolto il workshop UGISS [ <font face=""><a href="http://www.ugiss.org/Content/Event/Workshop-UGISS-R2-Alessandria.aspx">http://www.ugiss.org/Content/Event/Workshop-UGISS-R2-Alessandria.aspx</a> ]. Vorrei ringraziare tutti gli speaker per la loro disponibilità e competenza: Davide Mauri, Gianluca Hotz, Andrea Benedetti, Marco Russo e Alberto Ferrari. Professionisti davvero eccezionali che hanno reso possibile la realizzazione di un evento in una sede (Università) e luogo (Alessandria) insoliti.</font></p> <p>Un grazie anche ai partecipanti che sono accorsi numerosi.</p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/97869.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2010/01/16/97869.aspx Sat, 16 Jan 2010 00:08:02 GMT http://blogs.ugidotnet.org/dmantovani/archive/2010/01/16/97869.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/97869.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/97869.aspx "Subclassing" attraverso l'overload di cast implicito http://blogs.ugidotnet.org/dmantovani/archive/2009/04/08/95901.aspx <p><font face="Tahoma">Si immagini di voler creare una versione specializzata di cookie MyCookie.</font></p> <p><font face="Tahoma">La scelta più intuitiva è quella di scrivere una classe MyCookie che eredita da System.Web.HttpCookie</font></p> <p><!-- code formatted by http://manoli.net/csharpformat/ --></p> <div class="csharpcode"> <pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> MyCookie : System.Web.HttpCookie</pre> <pre>{</pre> <pre class="alt"> <span class="rem">// ...</span></pre> <pre>}</pre> </div> <p> </p> <p>per poi usarla in questo modo</p> <p><!-- code formatted by http://manoli.net/csharpformat/ --></p> <div class="csharpcode"> <pre class="alt">MyCookie cookie = <span class="kwrd">new</span> MyCookie();</pre> <pre>Response.Cookies.Add(cookie);</pre> </div> <p> </p> <p>Purtroppo <font face="Courier New">HttpCookie</font> è sealed e quindi non estendibile.</p> <p>Volendo preservare la precedente sintassi, è tuttavia possibile creare una sorta di "subclassing" facendo l'overload dell'operatore di cast implicito da <font face="Courier New">MyCookie</font> a <font face="Courier New">HttpCookie</font>. Questo consente di utilizzare <font face="Courier New">MyCookie</font> laddove è richiesta una istanza di <font face="Courier New">HttpCookie</font>.</p> <p><!-- code formatted by http://manoli.net/csharpformat/ --></p> <div class="csharpcode"> <pre class="alt"><span class="kwrd">public</span> <span class="kwrd">class</span> MyCookie </pre> <pre>{</pre> <pre class="alt"> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">implicit</span> <span class="kwrd">operator</span> HttpCookie(MyCookie cookie)</pre> <pre> {</pre> <pre class="alt"> <span class="kwrd">return</span> <span class="kwrd">new</span> HttpCookie(...);</pre> <pre> }</pre> <pre class="alt">}</pre> </div> <p> </p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/95901.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2009/04/08/95901.aspx Wed, 08 Apr 2009 00:13:04 GMT http://blogs.ugidotnet.org/dmantovani/archive/2009/04/08/95901.aspx#feedback 1 http://blogs.ugidotnet.org/dmantovani/comments/commentRss/95901.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/95901.aspx Brahma http://blogs.ugidotnet.org/dmantovani/archive/2008/10/25/94374.aspx <p><a href="http://brahma.ananthonline.net/">Brahma</a> è una interessante libreria open-source, scritta per .Net 3.5, il cui scopo è quello di fornire un modello di programmazione astratto per fare calcolo parallelo.<br /> Implementa un modello a provider che la rende aperta verso diversi "processori" per il calcolo.<br /> Di suo offre un provider che sfrutta, tramite DirectX, la GPU.</p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/94374.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/10/25/94374.aspx Sat, 25 Oct 2008 00:42:29 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/10/25/94374.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/94374.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/94374.aspx La notte dei ricercatori (Università del Piemonte Orientale) http://blogs.ugidotnet.org/dmantovani/archive/2008/09/21/94100.aspx <p><a href="http://www.mfn.unipmn.it/Attivit--d/Convegni-e/Notte-dei-/index.htm"><img height="242" alt="La notte dei ricercatori" width="795" src="/images/blogs_ugidotnet_org/dmantovani/Universita/NotteRicercatori.jpg" /></a></p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/94100.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/09/21/94100.aspx Sun, 21 Sep 2008 18:29:54 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/09/21/94100.aspx#feedback 1 http://blogs.ugidotnet.org/dmantovani/comments/commentRss/94100.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/94100.aspx Real World Functional Programming http://blogs.ugidotnet.org/dmantovani/archive/2008/09/03/93922.aspx <p><font face="Tahoma">Vorrei segnalare un libro che sto leggendo nei ritagli di tempo: <a href="http://www.functional-programming.net/">Real World Functional Programming</a>.<br /> Non è ancora completo ma i primi capitoli sono già disponibili (a pagamento) in formato elettronico. E' un libro interessante e con un taglio originale. Tratta dello stile di programmazione funzionale, argomento che sta acquistando importanza per diverse ragioni (vedi <a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx">LINQ</a>, <a href="http://msdn.microsoft.com/en-us/magazine/cc163329.aspx">PLINQ</a>, <a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx">PFX</a>, ...).</font></p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/93922.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/09/03/93922.aspx Wed, 03 Sep 2008 19:35:24 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/09/03/93922.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/93922.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/93922.aspx How I got Started in Software Development http://blogs.ugidotnet.org/dmantovani/archive/2008/07/16/93417.aspx <p>Rispondo anche io all'<a href="http://blogs.ugidotnet.org/rucka/archive/2008/07/15/93411.aspx">invito</a> di Gianluca...</p> <p><strong><em>A quale età hai cominciato a programmare?</em></strong></p> <p>A 12 anni nell'ormai lontano 1985.<br /> </p> <p><strong><em>Come hai cominciato a programmare?</em></strong></p> <p>Le mie prime esperienze con la programmazione coincidono con i primi contatti con il computer. Nel 1985, i miei genitori mi regalarono un corso di informatica con computer annesso (la marca del computer in dotazione era "Laser", computer dei quali non ho più sentito parlare). Il mio interesse iniziale è stato, come per molti, la curiosità verso i videogame. Nel corso mi furono insegnati i rudimenti di BASIC con il quale cominciai a fare i primi esperimenti, o per meglio dire, improvvisazioni. Siccome era complesso inventare dei programmi, ho preferito imparare copiando dei listati da riviste che in quel periodo spopolavano (chi ricorda il mitico "List"?!).</p> <p><strong><em>Qual’è stato il tuo primo linguaggio di programmazione?</em></strong></p> <p>BASIC.</p> <p><strong></strong></p> <p><strong><em>Qual’è stato il primo programma vero che hai scritto?</em></strong></p> Non ne sono certo ma credo che il primo programma "vero" fosse un semplice videogame, nel quale un personaggio costruito a - puzzle di - caratteri doveva rincorrere un oggetto in movimento nel tentativo di acchipparlo.<br /> <p><strong><em>Quali linguaggi hai usato da quando hai cominciato a programmare?</em></strong></p> <p>In ordine temporale:</p> <p>BASIC, Turbo Pascal, Assembler Z80, Assembler Motorola 68000, C, Basic di Microsoft Access 2.0, Lisp/Scheme, Prolog, ML, C++, Visual Basic 5 e 6, VBScript, JavaScript, C#<br /> </p> <p><strong><em>Quando è stato il tuo primo vero lavoro da programmatore?</em></strong></p> <p>Nel 1994, insiemi ad alcuni amici e compagni di Università, ricevemmo l'incarico di sviluppare un'applicazione per la gestione delle attività (chi fa che cosa, per quanto tempo, quando, ...) del personale interno all'azienda committente. L'applicazione continuò ad essere utilizzata fino al 1999.<br /> </p> <p><strong><em>Con il senno di poi, rifaresti lo stesso il programmatore? Ricominceresti a programmare?</em></strong></p> <p>Probabilmente sì visto che l'informatica è sempre stata la mia passione principale. Ho però un po' di rammarico per le altre passioni che ho un po' accantonato: la matematica e la fisica.<br /> <strong></strong></p> <p><strong><em>Se ci fosse una cosa che hai imparato nella tua carriera e che vorresti dire ai giovani programmatori, cosa diresti?</em></strong></p> <p>Lavorate con passione. Non accontentatevi: continuate a dedicare tempo all'apprendimento e siate sempre alla ricerca di un lavoro stimolante. Lavorate con umiltà: c'è sempre qualcuno che ha qualcosa da insegnarvi. Se potete trasmettere qualcosa di appreso a qualcuno, fatelo: trasparenza, comunicazione e sincerità sono doti essenziali.<br /> </p> <p><strong><em>Qual’è la cosa più divertente che hai programmato?</em></strong></p> <p>Probabilmente all'Università nel corso di linguaggi formali: un compilatore, per una variante del Pascal, che doveva produrre codice macchina da far girare su un simulatore di un processore simil Z80.<br /> </p> <p><strong><em>Adesso è l’ora di taggare qualcun’altro...</em></strong></p> <p><a href="http://blogs.ugidotnet.org/dsenatore/Default.aspx">Davide Senatore</a><span style="font-style: italic;"><br /> </span></p> <p><a href="http://blogs.ugidotnet.org/bressan/Default.aspx">Cristian Bressan</a></p> <p><a href="http://blogs.ugidotnet.org/marcom/Default.aspx">Marco Minerva</a></p> <p><a href="http://blogs.ugidotnet.org/FCanepari/Default.aspx">Fulvio Canepari</a></p> <p><a href="http://blogs.ugidotnet.org/Nick60/Default.aspx">Nicolò Carandini</a></p> <p><a href="http://blogs.ugidotnet.org/stefandemetz/Default.aspx">Stefan Demetz</a><span style="font-style: italic;"></span></p><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/93417.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/07/16/93417.aspx Wed, 16 Jul 2008 00:13:33 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/07/16/93417.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/93417.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/93417.aspx Custom DropDownList simile a ListViewSelector in SharePoint http://blogs.ugidotnet.org/dmantovani/archive/2008/05/22/92763.aspx <span style="FONT-FAMILY: Tahoma">La toolbar, presente di norma su tutte le liste SharePoint (quindi anche le Document Library), mostra una DropDownList che permette di selezionare la vista da applicare:<br /> <br /> </span> <div style="TEXT-ALIGN: center"><img height="116" alt="ListViewSelector" width="168" src="/images/blogs_ugidotnet_org/dmantovani/SharePoint/ListViewSelector.jpg" /><br /> </div> <span style="FONT-FAMILY: Tahoma"><br /> Comportamento e aspetto grafico di questa DropDownList sono implementati nel controllo Microsoft.SharePoint.WebControls.ListViewSelector.<br /> Questo controllo è riutilizzabile se si vuole permettere la selezione di una vista di una lista.<br /> E se invece si volesse semplicemente imitarne l'aspetto grafico? <br /> Curiosando un po' è possibile notare qual è l'HTML generato:<br /> <br /> <span style="FONT-FAMILY: Courier New">&lt;table border="0" cellpadding="0" cellspacing="0"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">&lt;tr&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">    &lt;td nowrap="nowrap" onmouseout="this.className='ms-viewselector'" class="ms-toolbar ms-viewselector" id="SomeID"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">        &lt;span style="display: none;"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">            &lt;menu compactmode="true" id="SomeID_Menu" type="ServerMenu"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;ie:menuitem _moz-userdefined="" menugroupid="100" text="One" onmenuclick="alert('One');" type="option" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;ie:menuitem _moz-userdefined="" menugroupid="300" text="Two" onmenuclick="alert('Two');" type="option" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;ie:menuitem _moz-userdefined="" menugroupid="400" text="Three" onmenuclick="alert('Three');" iconsrc="/_layouts/images/modifyview.gif" type="option" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;ie:menuitem _moz-userdefined="" menugroupid="400" text="Four" onmenuclick="alert('Four');" iconsrc="/_layouts/images/createview.gif" type="option" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">            &lt;/menu&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">        &lt;/span&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">        &lt;span title="Open Menu"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">            &lt;div nowrap="nowrap" oncontextmenu="this.click(); return false;" foa="MMU_GetMenuFromClientId('SomeID_Anchor')" onclick="MMU_Open(byid('SomeID_Menu'), MMU_GetMenuFromClientId('SomeID_Anchor'),event,true, 'SomeID', 0);" hoverinactive="ms-viewselector" hoveractive="ms-viewselectorhover" onmouseover="MMU_PopMenuIfShowing(this);MMU_EcbTableMouseOverOut(this, true)" class="ms-viewselector"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;a serverclientid="SomeID_Anchor" menutokenvalues="MENUCLIENTID=SomeID_Anchor,TEMPLATECLIENTID=SomeID_Menu" oncontextmenu="this.click(); return false;" onclick="javascript:return false;" onkeydown="MMU_EcbLinkOnKeyDown(byid('SomeID_Menu'), MMU_GetMenuFromClientId('SomeID_Anchor'), event);" onfocus="MMU_EcbLinkOnFocusBlur(byid('SomeID_Menu'), this, true);" style="cursor: pointer; white-space: nowrap;" href="#" accesskey="W" id="SomeID_Anchor"&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                    All Documents</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                    &lt;img border="0" alt="Use SHIFT+ENTER to open the menu (new window)." src="/_layouts/images/blank.gif" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;/a&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">                &lt;img align="absbottom" alt="" src="/_layouts/images/blank.gif" /&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">            &lt;/div&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">        &lt;/span&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">    &lt;/td&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">&lt;/tr&gt;</span><br style="FONT-FAMILY: Courier New" /> <span style="FONT-FAMILY: Courier New">&lt;/table&gt;</span><br style="FONT-FAMILY: Courier New" /> <br /> In particolare è possibile notare come sia sufficiente aggiungere elementi del tipo<br /> <br /> </span><span style="FONT-FAMILY: Tahoma"><span style="FONT-FAMILY: Courier New">&lt;ie:menuitem _moz-userdefined="" menugroupid="100" text="One" onmenuclick="alert('One');" type="option" /&gt;</span></span><br /> <span style="FONT-FAMILY: Tahoma"><br /> per avere ulteriori scelte nella DropDownList. <br /> <span style="FONT-FAMILY: Courier New">onmenuclick</span> permette di definire il codice JavaScript da eseguire quando si sceglie quel particolare elemento.<br /> <span style="FONT-FAMILY: Courier New">text</span> definisce il testo dei singoli item.<br /> </span><span style="FONT-FAMILY: Tahoma"><span style="FONT-FAMILY: Courier New">menugroupid</span></span><span style="FONT-FAMILY: Tahoma"> permette di raggruppare più elementi (quelli che hanno pari valore di </span><span style="FONT-FAMILY: Tahoma"><span style="FONT-FAMILY: Courier New">menugroupid</span></span><span style="FONT-FAMILY: Tahoma">).<br /> E' inoltre possibile visualizzare, a fianco di ciascun item, una immagine.<br /> A questo punto il gioco è fatto: basta implementare un proprio WebControl in grado di produrre codice HTML simile a quello mostrato.</span><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/92763.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/05/22/92763.aspx Thu, 22 May 2008 02:06:10 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/05/22/92763.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/92763.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/92763.aspx Parallel C# http://blogs.ugidotnet.org/dmantovani/archive/2008/05/14/92658.aspx <span style="font-family: Tahoma;">La diffusione dei processori <a href="http://en.wikipedia.org/wiki/Multi-core_%28computing%29">multi-core</a>, anzi <a href="http://en.wikipedia.org/wiki/Manycore_processing_unit">many-core</a>, offre nuove opportunità a tutti gli sviluppatori e non più soltanto ad una élite di persone operanti in settori di nicchia (calcolo scientifico, ...).</span><span style="font-family: Tahoma;"><br /> Per sfruttare in modo efficace queste opportunità è necessario un nuovo grado di astrazione nei linguaggi e paradigmi di programmazione: operare con i concetti quali concorrenza, sincronizzazione, ... ad alto livello senza doversi preoccupare di "dettagli" di basso livello (lock, semafori, ...).</span><br /> <span style="font-family: Tahoma;">Le problematiche non sono di facile soluzione. Questo ha dato origine ad una serie di filoni di ricerca, alla cui base spesso ci sono scelte piuttosto differenti.<br /> In questo panorama Microsoft si pone con un atteggiamento che, a mio avviso, cerca di equilibrare aspetti innovativi di ricerca con una buona dose di pragmatismo. A tal proposito si può ad esempio dare un'occhiata alle cosiddette <a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx">PFX</a> (Parallel Extensions to the .Net Framework 3.5), PLINQ, ... Questi lavori tentano, almeno al momento, di catturare le peculiarità del calcolo parallelo sotto forma di librerie di codice.<br /> Ci sono altri progetti, di cui "<a href="http://www.parallelcsharp.com/">Parallel C#</a>" è sicuramente un esemplare interessante, che invece si ripropongono di estendere i linguaggi di programmazione stessi al fine di incorporare le astrazioni del caso.</span><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/92658.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/05/14/92658.aspx Wed, 14 May 2008 00:31:21 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/05/14/92658.aspx#feedback 6 http://blogs.ugidotnet.org/dmantovani/comments/commentRss/92658.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/92658.aspx Paginazione dei risultati di una query http://blogs.ugidotnet.org/dmantovani/archive/2008/03/26/91865.aspx <span style="font-family: Tahoma;">Il problema di dover paginare i risultati di una query a SQL Server (ma più in generale ad un qualunque DBMS) ricorre spesso, specialmente nelle applicazioni distribuite dove è fondamentale ridurre al minimo la quantità di dati trasportati sul canale.<br /> SQL Server 2005 offre alcuni operatori SQL che permettono di costruire uno "schema" per tradurre una qualunque query nella equivalente versione che restituisce la sola pagina di dati voluta.<br /> Supponiamo ad es. di voler paginare i dati della seguente query (Northwind):<br /> <br /> <span style="font-family: Courier New; background-color: rgb(51, 102, 255);">SELECT *</span><br style="font-family: Courier New; background-color: rgb(51, 102, 255);" /> <span style="font-family: Courier New; background-color: rgb(51, 102, 255);">FROM Customers</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New; background-color: rgb(255, 255, 0);">ORDER BY CustomerID ASC</span><br style="font-family: Courier New;" /> <br /> Isoliamo la clausola ORDER BY dal resto della query ottenendo quindi qualcosa del tipo<br /> <br /> <span style="font-family: Courier New;">SELECT *</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">FROM (</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    <span style="background-color: rgb(51, 102, 255);">SELECT </span><br style="background-color: rgb(51, 102, 255);" /> <span style="background-color: rgb(51, 102, 255);">        *</span>,<br />         ROW_NUMBER() OVER (<span style="background-color: rgb(255, 255, 0);">ORDER BY CustomerID ASC</span>) AS [_RowNum]</span><span style="font-family: Courier New;"></span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    <span style="background-color: rgb(51, 102, 255);">FROM Customers</span></span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;"><span style="font-family: Courier New;">    ) AS T</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">WHERE [_RowNum] BETWEEN @Min AND @Max</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">ORDER BY [_RowNum] ASC</span><br /> <br /> <span style="font-family: Tahoma;"> I colori mostrano le parti della query SQL prima e dopo la trasformazione. I parametri @Min e @Max devono essere sostituiti rispettivamente con l'indice del primo record e dell'ultimo record della pagina desiderata.</span><br style="font-family: Tahoma;" /> <span style="font-family: Tahoma;"> Lo schema indicato, con alcune limitazioni (ad es. è obbligatorio specificare esplicitamente la clausola ORDER BY), permette di trasformare una query complessa a piacere nell'equivalente paginabile. Detto questo, è possibile costruire una stored procedure che, facendo uso degli statement SQL dinamici, permette di paginare i risultati di una qualunque query:</span><br /> <br /> <span style="font-family: Courier New;">CREATE PROCEDURE [dbo].[spQuery]</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @Sql NVARCHAR(MAX) = N'',</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @OrderBy NVARCHAR(MAX) = N'',</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @PageNumber INT = 1 OUT,</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @PageSize INT = 0,</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @NoRecordCount SMALLINT = 0,</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @RecordCount INT = 0 OUT</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">AS </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    DECLARE @SqlString NVARCHAR(MAX)</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    DECLARE @PageCount INT</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    DECLARE @Min INT</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    DECLARE @Max INT</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    DECLARE @RowNum INT</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    SET @Sql = LTRIM(RTRIM(ISNULL(@Sql, N'')))</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @Sql = N'' </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        RETURN 1 -- Missed Sql.</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    SET @OrderBy = LTRIM(RTRIM(ISNULL(@OrderBy, N'')))</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @OrderBy = N'' </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        RETURN 2 -- Missed OrderBy.</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @PageNumber &lt;= 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        SET @PageNumber = 1</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">-- Vengono contati i record.</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    SET @RecordCount = -1</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @NoRecordCount = 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @SqlString = N'SELECT @RecordCount = COUNT(*) FROM (' + @Sql + N') AS T'</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            EXEC sp_executesql @SqlString, N'@RecordCount int out', @RecordCount OUT</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        END</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">-- Se occorre contare i record...</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @PageSize = 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @PageCount = 1</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @PageNumber = 1</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        END</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    ELSE </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            IF @RecordCount &lt; 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                    SET @PageCount = 0</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                END</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            ELSE </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                    SET @PageCount = CEILING(CAST(@RecordCount AS FLOAT) / CAST(@PageSize AS FLOAT))</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        -- @PageNumber = 0  =&gt; ultima pagina</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        -- @PageNumber = N  =&gt; N-esima pagina o ultima se @PageNumber &gt; @PageCount</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        -- @PageNumber = -N =&gt; @PageNumber = @PageCount - N (penultima, ...)</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        -- Se alla fine @PageNumber &lt; 0 =&gt; @PageNumber = @PageCount</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                    IF @PageNumber &lt;= 0</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                        OR @PageNumber &gt; @PageCount </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                        SET @PageNumber = @PageCount - @PageNumber</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                    IF @PageNumber &lt;= 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                        SET @PageNumber = @PageCount</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">                END</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        END</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    -- Deve essere rimpiazzata solo la prima occorrenza di SELECT ... =&gt; SELECT ROW_NUMBER() OVER (...) AS [_RowNum]</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @PageSize &gt; 0 AND @NoRecordCount &lt;&gt; 0</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        SET @SqlString = N'SELECT TOP ' + CAST((@PageNumber * @PageSize) AS NVARCHAR(MAX)) + N' * '</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    ELSE</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        SET @SqlString = N'SELECT * '</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    SET @SqlString = @SqlString +</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        N'FROM (' + </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        N'SELECT ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + N') AS [_RowNum],' + SUBSTRING(@Sql, 7, LEN(@Sql) - 6) +</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        N') AS T'</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    IF @PageSize &gt; 0 </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        BEGIN</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @Min = @PageSize * ( @PageNumber - 1 ) + 1</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @Max = @Min + @PageSize - 1</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">            SET @SqlString = @SqlString + N' WHERE [_RowNum] BETWEEN @Min AND @Max'</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">        END</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    SET @SqlString = @SqlString + N' ORDER BY [_RowNum] ASC'</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    EXEC sp_executesql @SqlString, N'@Min int, @Max int', @Min = @Min, @Max = @Max</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    RETURN 0 -- No error.</span><br style="font-family: Courier New;" /> <br /> Esempio di invocazione:<br /> <br /> <span style="font-family: Courier New;">DECLARE @RC INT</span><br style="font-family: Courier New;" /> <br style="font-family: Courier New;" /> <span style="font-family: Courier New;">EXEC dbo.spQuery </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    N'SELECT * FROM Customers',    -- Query SQL a meno della clausola ORDER BY principale</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    N'CustomerID ASC',             -- Clausola ORDER BY principale</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    1,                             -- Numero di pagina voluto (pagina 1 di ...)</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    3,                             -- Numero di record per pagina (3 record per pagina)</span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    0,                             -- Mi interessa avere il conteggio dei record totali (senza paginazione) </span><br style="font-family: Courier New;" /> <span style="font-family: Courier New;">    @RC OUT                        -- Numero di record totali</span></span></span><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/91865.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/03/26/91865.aspx Wed, 26 Mar 2008 00:55:33 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/03/26/91865.aspx#feedback http://blogs.ugidotnet.org/dmantovani/comments/commentRss/91865.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/91865.aspx SharePoint, ListView Control e Toolbar http://blogs.ugidotnet.org/dmantovani/archive/2008/03/14/91689.aspx <span style="font-family: Tahoma;">SharePoint offre il controllo <span style="font-family: Courier New;">ListView</span> (namespace </span><span style="font-family: Tahoma;">controllo <span style="font-family: Courier New;">Microsoft.SharePoint.WebControls</span></span><span style="font-family: Tahoma;">) che è possibile utilizzare per renderizzare una qualunque SPList all'interno di una pagina, di una Web Part custom, ... Es:<br /> <br /> </span><span id="_ctl0_MainContent_PostFlatView"><span><font size="2"><span style="font-family: Courier;">SPList list = SPContext.Current.Web.Lists["Company documents"];</span><br style="font-family: Courier;" /> </font></span></span><span id="_ctl0_MainContent_PostFlatView"><span><font size="2"><span style="font-family: Courier;">ListView lv = new ListView();</span><br style="font-family: Courier;" /> <span style="font-family: Courier;">lv.ListId = list.ID.ToString();</span><br style="font-family: Courier;" /> <span style="font-family: Courier;">lv.ViewId = list.DefaultView.ID.ToString();</span><br style="font-family: Courier;" /> <span style="font-family: Courier;"></span></font></span></span><span id="_ctl0_MainContent_PostFlatView"><span><font size="2"><span style="font-family: Courier;">Controls.Add(lv);</span></font></span></span><br /> <span style="font-family: Tahoma;"><br /> <img width="972" height="68" src="/images/blogs_ugidotnet_org/dmantovani/SharePoint/SPList.jpg" alt="" /><br /> <br /> Se l'utilizzo di <span style="font-family: Courier New;">ListView </span>è semplice e intuitivo, è invece meno banale capire qual è il controllo da utilizzare per renderizzare la toolbar della SPList. <br /> <br /> <img src="/images/blogs_ugidotnet_org/dmantovani/SharePoint/SPToolbar.jpg" alt="" /><br /> <br /> Il seguente frammento di codice illustra il funzionamento di <span style="font-family: Courier New;">ViewToolbar</span>, il controllo che renderizza appunto la toolbar:<br /> <br /> </span><span id="_ctl0_MainContent_PostFlatView"><span><font size="2"><span style="font-family: Courier;" /></font></span></span><span id="_ctl0_MainContent_PostFlatView"><span><font size="2"><span style="font-family: Courier;"> SPList list = SPContext.Current.Web.Lists["Company documents"];</span><br style="font-family: Courier;" /> <br style="font-family: Courier;" /> <span style="font-family: Courier;">ViewToolBar toolbar = new ViewToolBar();</span><br style="font-family: Courier;" /> <span style="font-family: Courier;">SPContext context = SPContext.GetContext(this.Context, list.DefaultView.ID, list.ID, SPContext.Current.Web);</span><br style="font-family: Courier;" /> <span style="font-family: Courier;">toolbar.RenderContext = context;</span><br style="font-family: Courier;" /> <span style="font-family: Courier;">Controls.Add(toolbar);</span><br style="font-family: Courier;" /> <br /> </font></span></span><img src="http://blogs.ugidotnet.org/dmantovani/aggbug/91689.aspx" width="1" height="1" /> Daniele Mantovani http://blogs.ugidotnet.org/dmantovani/archive/2008/03/14/91689.aspx Fri, 14 Mar 2008 01:22:59 GMT http://blogs.ugidotnet.org/dmantovani/archive/2008/03/14/91689.aspx#feedback 4 http://blogs.ugidotnet.org/dmantovani/comments/commentRss/91689.aspx http://blogs.ugidotnet.org/dmantovani/services/trackbacks/91689.aspx