WCF http://blogs.ugidotnet.org/PietroLibroBlog/category/WCF.aspx WCF it-IT Pietro Libro pietro.libro@libero.it Subtext Version 2.6.0.0 Modi diversi di recuperare il numero di messaggi in una coda MSMQ http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/01/28/modi-diversi-di-recuperare-il-numero-di-messaggi-in-una.aspx <p>Ultimamente mi trovo a lavorare su di un progetto che utilizza WCF e <a href="http://en.wikipedia.org/wiki/Microsoft_Message_Queuing" target="_blank">MSMQ</a>. Una delle classiche operazioni quando si lavora con queste tecnologie è sicuramente recuperare il numero di messaggi presenti in una coda. Tra documentazione e ricerche su internet, alla fine si “scopre” che ci sono diversi metodi per risolvere lo stesso problema:</p> <ol> <li>Cursori di MSMQ </li> <li>Utilizzo di GetAllMessages </li> <li>Utilizzo di GetEnumerator2 </li> <li>PowerShell </li> <li>Performance Counter </li> </ol> <p>Traducendo il tutto in righe di codice, per il punto 1) abbiamo:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">int</span> CountByCursor() { <span class="kwrd">int</span> count = 0; Cursor cursor = _messageQueue.CreateCursor(); Message m = CursorPeekWithoutTimeout(cursor, PeekAction.Current); <span class="kwrd">if</span> (m != <span class="kwrd">null</span>) { count = 1; <span class="kwrd">while</span> ((m = CursorPeekWithoutTimeout(cursor, PeekAction.Next)) != <span class="kwrd">null</span>) { count++; } <span class="kwrd">if</span> (m != <span class="kwrd">null</span>) m.Dispose(); } cursor.Dispose(); <span class="kwrd">return</span> count; } <span class="kwrd">private</span> Message CursorPeekWithoutTimeout(Cursor cursor, PeekAction action) { Message ret = <span class="kwrd">null</span>; <span class="kwrd">try</span> { ret = _messageQueue.Peek(<span class="kwrd">new</span> TimeSpan(1), cursor, action); } <span class="kwrd">catch</span> (MessageQueueException mqe) { <span class="kwrd">if</span> (mqe.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout) { <span class="kwrd">throw</span>; } } <span class="kwrd">return</span> ret; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Sinceramente questo è il metodo che più non mi piace, sarà per la parola “Cursore”, sarà per la gestione dell’eccezione, sarà perchè la vedo poco pulita. </p> <p>Passiamo al punto 2):</p> <pre class="csharpcode"> <span class="kwrd">public</span> <span class="kwrd">int</span> CountByGetAllMessages() { <span class="kwrd">return</span> _messageQueue.GetAllMessages().Length; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Semplice e pulita, ma come vedremo a breve, le prestazioni scendono con l’aumentare dei messaggi in coda.</p> <p>Punto 3), “GetMessageEnumerator2”:</p> <pre class="csharpcode">var x = _messageQueue.GetMessageEnumerator2(); <span class="kwrd">int</span> counter = 0; <span class="kwrd">while</span> (x.MoveNext()) { counter++; } <span class="kwrd">return</span> counter;</pre> <p>Sfruttiamo il <em>MessageEnumerator</em> ritornato dal metodo <em>GetEnumerator2</em> ed iteriamo per spostare il cursore fino alla fine della coda.</p> <p>Punto 4), “PowerShell” (in questo caso mi sono limitato a copiare del codice trovato in rete):</p> <pre class="csharpcode">var path = <span class="kwrd">string</span>.Format(<span class="str">@"\\{0}\root\CIMv2"</span>, machine); ManagementScope scope; <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(username)) { scope = <span class="kwrd">new</span> ManagementScope(path); } <span class="kwrd">else</span> { var options = <span class="kwrd">new</span> ConnectionOptions { Username = username, Password = password }; scope = <span class="kwrd">new</span> ManagementScope(path, options); } scope.Connect(); <span class="kwrd">if</span> (queuePath.StartsWith(<span class="str">".\\")) queuePath = queuePath.Replace("</span>.\\<span class="str">", string.Format("</span>{0}\\<span class="str">", machine)); string queryString = String.Format("</span>SELECT * FROM Win32_PerfFormattedData_msmq_MSMQQueue<span class="str">"); var query = new ObjectQuery(queryString); var searcher = new ManagementObjectSearcher(scope, query); IEnumerable&lt;int&gt; messageCountEnumerable = from ManagementObject queue in searcher.Get() select (int)(UInt64)queue.GetPropertyValue("</span>MessagesInQueue"); var x = messageCountEnumerable.First(); <span class="kwrd">return</span> x;</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>ed infine il punto 5) “Performance Counter”:</p> <pre class="csharpcode">System.Diagnostics.PerformanceCounter backupQueueCounter = <span class="kwrd">new</span> System.Diagnostics.PerformanceCounter( <span class="str">"MSMQ Queue"</span>, <span class="str">"Messages in Queue"</span>, <span class="str">"queue_path"</span>); <span class="kwrd">return</span> backupQueueCounter.NextValue();</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Bene, ora quale usare ? Proviamo con un piccolo test: ad una coda privata aggiungiamo 10.000 messaggi per volta (all’interno di un ciclo) e proviamo ad utilizzare i metodi su descritti per recuperare il numero di messaggi presenti in coda (si suppone che tra un conteggio e l’altro nella coda non vengano aggiunti altri messaggi). Iteriamo il procedimento per tre volte. </p> <p>Di seguito i risultati ottenuti (espressi in millisecondi, per le misure del tempo di esecuzione è stata utilizzata la classe <em>System.Diagnostics.Stopwatcher</em>):</p> <p><strong>Prima Iterazione</strong></p> <table cellspacing="0" cellpadding="0" border="0"><tbody> <tr> <td width="80">#Msgs</td> <td width="80">MSMQ Cursor</td> <td width="35">GetAllMessages</td> <td width="65">GetEnumerator2</td> <td width="118">PowerShell</td> <td width="97">Performance C.</td> </tr> <tr> <td width="80">10.000</td> <td width="80">449,816</td> <td width="35">580,703</td> <td>36,37</td> <td>78,543</td> <td>351,86</td> </tr> <tr> <td width="80">20.000</td> <td width="80">928,18</td> <td width="35">1.297,72</td> <td>78,16</td> <td>9,888</td> <td>0,462</td> </tr> <tr> <td width="80">30.000</td> <td width="80">1.340,44</td> <td width="35">1.854,52</td> <td>137,82</td> <td>10,563</td> <td>1,121</td> </tr> <tr> <td width="80">40.000</td> <td width="80">1.769,73</td> <td width="35">2.656,28</td> <td>194,652</td> <td>12,061</td> <td>3,187</td> </tr> <tr> <td width="80">50.000</td> <td width="80">2.188,74</td> <td width="35">3.427,84</td> <td>190,672</td> <td>10,739</td> <td>0,452</td> </tr> <tr> <td width="80">60.000</td> <td width="80">2.631,29</td> <td width="35">3.909,71</td> <td>231,995</td> <td>10,219</td> <td>0,364</td> </tr> <tr> <td width="80">70.000</td> <td width="80">3.006,52</td> <td width="35">4.771,09</td> <td>264,112</td> <td>5.802,42</td> <td>0,462</td> </tr> <tr> <td width="80">80.000</td> <td width="80">3.469,49</td> <td width="35">6.116,47</td> <td>309,691</td> <td>10,075</td> <td>0,545</td> </tr> <tr> <td width="80">90.000</td> <td width="80">4.000,00</td> <td width="35">6.134,66</td> <td>372,885</td> <td>9,876</td> <td>0,435</td> </tr> <tr> <td width="80">100.000</td> <td width="80">4.544,33</td> <td width="35">6.932,08</td> <td>424,196</td> <td>9,024</td> <td>0,41</td> </tr> </tbody></table> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_10.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_thumb.png" width="244" height="148" /></a> <p><strong>Seconda Iterazione</strong></p> <table cellspacing="0" cellpadding="0" border="0"><tbody> <tr> <td width="77">#Msgs</td> <td width="78">MSMQ Cursor</td> <td width="40">GetAllMessages</td> <td width="65">GetEnumerator2</td> <td width="118">PowerShell</td> <td width="97">Performance C.</td> </tr> <tr> <td width="77">10.000</td> <td width="78">475,357</td> <td width="40">609,866</td> <td>38,022</td> <td>285,978</td> <td>351,955</td> </tr> <tr> <td width="77">20.000</td> <td width="78">912,591</td> <td width="40">1.315,49</td> <td>76,912</td> <td>10,453</td> <td>0,502</td> </tr> <tr> <td width="77">30.000</td> <td width="78">1.417,26</td> <td width="40">2.066,92</td> <td>122,745</td> <td>11,156</td> <td>0,366</td> </tr> <tr> <td width="77">40.000</td> <td width="78">1.901,66</td> <td width="40">2.718,64</td> <td>153,373</td> <td>9,947</td> <td>0,349</td> </tr> <tr> <td width="77">50.000</td> <td width="78">2.393,97</td> <td width="40">3.386,43</td> <td>203,553</td> <td>10,962</td> <td>0,358</td> </tr> <tr> <td width="77">60.000</td> <td width="78">2.659,28</td> <td width="40">4.546,84</td> <td>280,257</td> <td>9,832</td> <td>0,413</td> </tr> <tr> <td width="77">70.000</td> <td width="78">3.246,77</td> <td width="40">4.938,01</td> <td>278,404</td> <td>11,664</td> <td>0,517</td> </tr> <tr> <td width="77">80.000</td> <td width="78">3.718,89</td> <td width="40">5.881,67</td> <td>330,857</td> <td>13,688</td> <td>0,506</td> </tr> <tr> <td width="77">90.000</td> <td width="78">4.230,99</td> <td width="40">6.677,00</td> <td>362,374</td> <td>10,155</td> <td>0,508</td> </tr> <tr> <td width="77">100.000</td> <td width="78">4.832,89</td> <td width="40">7.585,19</td> <td>464,216</td> <td>16,495</td> <td>0,681</td> </tr> </tbody></table> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_12.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_thumb_4.png" width="244" height="148" /></a> <p><strong>Terza Iterazione</strong></p> <table cellspacing="0" cellpadding="0" width="541" border="0"><tbody> <tr> <td width="86">#Msgs</td> <td width="103">MSMQ Cursor</td> <td width="10">GetAllMessages</td> <td width="65">GetEnumerator2</td> <td width="118">PowerShell</td> <td width="161">Performance C.</td> </tr> <tr> <td width="86">10.000</td> <td width="103">533,294</td> <td width="10">621,392</td> <td>41,496</td> <td>79,286</td> <td width="161">376,431</td> </tr> <tr> <td width="86">20.000</td> <td width="103">911,513</td> <td width="10">1.338,41</td> <td>79,827</td> <td>9,354</td> <td width="161">0,38</td> </tr> <tr> <td width="86">30.000</td> <td width="103">1.339,34</td> <td width="10">2.123,46</td> <td>120,693</td> <td>12,969</td> <td width="161">0,414</td> </tr> <tr> <td width="86">40.000</td> <td width="103">1.799,28</td> <td width="10">2.658,01</td> <td>158,606</td> <td>9,423</td> <td width="161">0,374</td> </tr> <tr> <td width="86">50.000</td> <td width="103">2.196,96</td> <td width="10">3.221,87</td> <td>199,273</td> <td>10,413</td> <td width="161">0,426</td> </tr> <tr> <td width="86">60.000</td> <td width="103">2.562,49</td> <td width="10">4.140,15</td> <td>257,22</td> <td>8,81</td> <td width="161">0,411</td> </tr> <tr> <td width="86">70.000</td> <td width="103">3.358,83</td> <td width="10">4.715,56</td> <td>327,474</td> <td>14,808</td> <td width="161">0,53</td> </tr> <tr> <td width="86">80.000</td> <td width="103">4.417,58</td> <td width="10">6.690,44</td> <td>316,044</td> <td>17,334</td> <td width="161">0,825</td> </tr> <tr> <td width="86">90.000</td> <td width="103">4.185,52</td> <td width="10">6.229,67</td> <td>340,457</td> <td>11,773</td> <td width="161">0,396</td> </tr> <tr> <td width="86">100.000</td> <td width="103">4.407,13</td> <td width="10">6.658,46</td> <td>390,498</td> <td>12,944</td> <td width="161">0,589</td> </tr> </tbody></table> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_14.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/Modidiversidirecuperareilnumerodimessagg_ABED/image_thumb_5.png" width="244" height="148" /></a> <p>Dai risultati ottenuti si ottiene che l’utilizzo del “Performance Counter”, in caso di letture successive, sembrerebbe essere quello più efficiente. </p> <p>In attesa di altri giudizi ed approfondimenti :-).</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101412.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/01/28/modi-diversi-di-recuperare-il-numero-di-messaggi-in-una.aspx Mon, 28 Jan 2013 13:13:32 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/01/28/modi-diversi-di-recuperare-il-numero-di-messaggi-in-una.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101412.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101412.aspx DomusDotNet : We Want Web, grazie a tutti :-) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx <p>Ieri 9/3/12 si è svolto l’evento WeWantWeb organizzato da DomusDotNet presso la sede Microsoft di Roma. Le sessioni sono state registrare e quanto prima pubblicheremo Slide, codice sorgente degli esempi e Video, sul sito di <a href="http://www.domusdotnet.org/" target="_blank">DomusDotNet</a>. Grazie a tutti i partecipanti!!! Attendiamo i vostri feedback! Al prossimo evento <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/wlEmoticon-smile_2.png" />.</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000309_2.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Alessandro Mostarda e Massibo Bonanni" border="0" alt="Alessandro Mostarda e Massibo Bonanni" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000309_thumb.jpg" width="184" height="244" /></a><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000311_2.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Giorgio Di Nardo" border="0" alt="Giorgio Di Nardo" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000311_thumb.jpg" width="184" height="244" /></a><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000317_2.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Nicolò Carandini" border="0" alt="Nicolò Carandini" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000317_thumb.jpg" width="184" height="244" /></a><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000333_2.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Pietro Libro" border="0" alt="Pietro Libro" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000333_thumb.jpg" width="184" height="244" /></a><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000307_2.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="WP_000307" border="0" alt="WP_000307" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/WP_000307_thumb.jpg" width="184" height="244" /></a></p> <p>Da sinistra verso destra: <a href="http://www.alessandromostarda.com/" target="_blank">Alessandro Mostarda</a> e <a href="http://codetailor.blogspot.com/" target="_blank">Massimo Bonanni</a>, Giorgio Di Nardo, <a href="http://blogs.ugidotnet.org/Nick60/Default.aspx" target="_blank">Nick</a>, io <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/wlEmoticon-smile_2.png" />, parte di coloro che hanno avuto la pazienza di ascoltarci <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/7226c6221ecf_11545/wlEmoticon-smile_2.png" />.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100854.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx Sat, 10 Mar 2012 20:52:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100854.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100854.aspx DomusDotNet: We Want Web http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/02/12/domusdotnet-we-want-web.aspx <p>Come da titolo, evento interamente dedicato al mondo del Web!!! <strike>A breve apriranno le iscrizioni.</strike> Iscrizioni aperte!!!</p> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/DomusDotNet-We-Want-Web_12DF1/locandina_500x333_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="locandina_500x333" border="0" alt="locandina_500x333" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/DomusDotNet-We-Want-Web_12DF1/locandina_500x333_thumb.jpg" width="524" height="351" /></a> <p>Tutti i dettagli e l’agenda completa sulla pagina dell’evento: <a href="http://www.domusdotnet.org/eventi/wewantweb.aspx" target="_blank">WeWantWeb</a>. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100769.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/02/12/domusdotnet-we-want-web.aspx Sun, 12 Feb 2012 22:31:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/02/12/domusdotnet-we-want-web.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100769.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100769.aspx DomusDotNet: WCF Data Services (Terza Parte) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/25/domusdotnet-wcf-data-services-terza-parte.aspx <p>Terzo ed ultimo articolo (qualcuno dirà finalmente <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/DomusDotNet-WCF-Data-Services-Terza-Part_C471/wlEmoticon-smile_2.png" />) della serie dedicata ai WCF Data Services. Articolo completo su <a href="http://www.domusdotnet.org/articoli/wcf-data-services-%28parte-3%29.aspx" target="_blank">DomusDotNet</a>. Critiche, consigli e suggerimenti sono sempre ben accetti.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100729.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/25/domusdotnet-wcf-data-services-terza-parte.aspx Wed, 25 Jan 2012 14:59:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/25/domusdotnet-wcf-data-services-terza-parte.aspx#feedback 2 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100729.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100729.aspx OData T4 for C# http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/20/odata-t4-for-c.aspx <p>Annuncio fresco fresco (quasi <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/OData-T4_994A/wlEmoticon-smile_2.png" /> ) da parte del WCF Data Services Team Blog : <a title="http://blogs.msdn.com/b/astoriateam/archive/2012/01/19/announcing-odata-t4-for-c-preview-1.aspx" href="http://blogs.msdn.com/b/astoriateam/archive/2012/01/19/announcing-odata-t4-for-c-preview-1.aspx">http://blogs.msdn.com/b/astoriateam/archive/2012/01/19/announcing-odata-t4-for-c-preview-1.aspx</a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100715.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/20/odata-t4-for-c.aspx Fri, 20 Jan 2012 11:54:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/20/odata-t4-for-c.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100715.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100715.aspx MCTS 70-513 http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/17/mcts-70-513.aspx <p>Ieri, anche questo è andato. E’ stata una bella soddisfazione. Ora avanti per l’MCPD <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/302cff485d01_E43F/wlEmoticon-smile_2.png" />. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100707.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/17/mcts-70-513.aspx Tue, 17 Jan 2012 17:15:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/17/mcts-70-513.aspx#feedback 2 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100707.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100707.aspx DomusDotNet: WCF Data Services (Seconda Parte) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/11/domusdotnet-wcf-data-services-seconda-parte.aspx <p>Secondo articolo della serie dedicata ai WCF Data Services: utilizzo con Entity Framework, ed approfondimento su Service Operations. Nel codice allegato un client ASP.NET MVC di test. Articolo completo sul sito di <a href="http://www.domusdotnet.org/articoli/wcf-data-services-%28parte-2%29.aspx" target="_blank">DomusDotNet</a>. Al solito, consigli e suggerimenti sono sempre ben accetti <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/DomusDotNet-WCF-Data-Services-Seconda-Pa_60A5/wlEmoticon-smile_2.png" />.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100692.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/11/domusdotnet-wcf-data-services-seconda-parte.aspx Wed, 11 Jan 2012 07:56:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/01/11/domusdotnet-wcf-data-services-seconda-parte.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100692.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100692.aspx DomusDotNet: WCF Data Services (Prima parte) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx <p>Prima parte di una serie di articoli dedicati ai WCF Data Services, al protocollo OData e REST. Per gli interessati , articolo completo <a href="http://www.domusdotnet.org/articoli/wcf-data-services---prima-parte.aspx" target="_blank">qui</a>. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100645.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx Wed, 21 Dec 2011 01:00:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100645.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100645.aspx WCF, netsh e &ldquo;prenotazione&rdquo; URL http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/22/wcf-netsh-e-ldquoprenotazionerdquo-url.aspx <p>Post promemoria. Se abbiamo la necessità di eseguire l’hosting di un servizio WCF su Windows Vista, Windows Server 2008R2 o Windows 7 tramite ad esempio un’applicazione console (Windows Form o WPF <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/0514749c3f48_1319B/wlEmoticon-smile_2.png" />) è necessario eseguire una “prenotazione” dello spazio dei nomi URL per lo specifico account DOMAIN\User. Per eseguire questo scopo in modo programmatico (e non avere la necessità di creare un file d’installazione) allora possiamo scrivere del codice tipo:</p> <div id="codeSnippetWrapper" class="csharpcode-wrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">string</span> batContent = <span class="kwrd">string</span>.Format(<span class="str">@"netsh http add urlacl url=http://+:{0}/ user={1}\{2}"</span>,<br /> uriToRegister.Port, Environment.MachineName, Environment.UserName);<br /><br /><span class="kwrd">string</span> batPath = <span class="str">"NetBat.bat"</span>;<br />System.IO.File.WriteAllText(batPath, batContent);<br /><br />ProcessStartInfo startInfo = <span class="kwrd">new</span> ProcessStartInfo();<br />startInfo.UseShellExecute = <span class="kwrd">true</span>;<br />startInfo.Verb = <span class="str">"runas"</span>;<br />startInfo.FileName = <span class="str">"cmd.exe"</span>;<br />startInfo.Arguments = <span class="kwrd">string</span>.Format(<span class="str">"/c {0}{1}{0}"</span>, (<span class="kwrd">char</span>)34, batPath);<br /><br />Process p = System.Diagnostics.Process.Start(startInfo);<br />p.WaitForExit();</pre> </div> <p>per la registrazione dello spazio dei nomi URL nell’<em>urlacl</em> dello specifico account DOMAIN\User. Possiamo utilizzare del codice tipo:</p> <div id="codeSnippetWrapper" class="csharpcode-wrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">string</span> batContent = <span class="kwrd">string</span>.Format(<span class="str">@"netsh http delete urlacl url=http://+:{0}/ user={1}\{2}"</span>,<br /> uriToUniregister.Port, Environment.MachineName, Environment.UserName);</pre> </div> <p>per la rimozione. Il codice crea un file con estensione “.bat” eseguito tramite linea di comando. Ovviamente l’esecuzione del codice richiede l’elevazione dei privilegi dell’utente (se necessario). Il codice può essere utilizzato anche in caso di applicazioni ClickOnce. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100290.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/22/wcf-netsh-e-ldquoprenotazionerdquo-url.aspx Mon, 22 Aug 2011 23:08:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/22/wcf-netsh-e-ldquoprenotazionerdquo-url.aspx#feedback 1 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100290.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100290.aspx WCF Data Service (CTP2) e EF 4.1 http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/05/15/wcf-data-service-ctp2-e-ef-4.1.aspx <p>Chi usa i WCF Data Service (vedi ADO.NET Data Service), potrebbe incontrare qualche difficoltà nell’utilizzo di Entity Framework 4.1 utilizzando l’approccio Code First, “a causa” del <em>DbContext</em>, dato che un <em>DataService&lt;T&gt;</em> si aspetta  un T derivato da <em>ObjectContext . </em>“Under the hood” il <em>DbContext</em> utilizza <em>ObjectContext</em> e di conseguenza è facile immaginare una possibile soluzione al problema: eseguire l’<em>ovveride</em> del metodo <em>CreateDataSource </em>del <em>DataService&lt;T&gt; </em>ed utilizzare <em>l’ObjectContext</em> corrente. E’ sufficiente qualche ricerca tramite <em>Bing</em> o <em>Google</em> per trovare del codice di esempio. Per chi ha voglia di sperimentare, può a scaricare la versione WCF Data Service CTP 2 di Marzo 2011, per utilizzare il supporto “nativo” al <em>DbContext</em>. Il pacchetto d’installazione può essere scaricato qui: <a title="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=60fb0117-8cea-4359-b392-6b04cdc821be" href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=60fb0117-8cea-4359-b392-6b04cdc821be" target="_blank">http://www.microsoft.com/downloads/en/details.aspx?FamilyID=60fb0117-8cea-4359-b392-6b04cdc821be</a> dove tra l’altro è presente un <em>overview</em> delle modifiche apportare rispetto alla versione precedente (altre info si trovano qui: <a title="http://blogs.msdn.com/b/writingdata_services/archive/2011/03/09/march-2011-ctp-of-wcf-data-services-for-odata-v3-is-live.aspx" href="http://blogs.msdn.com/b/writingdata_services/archive/2011/03/09/march-2011-ctp-of-wcf-data-services-for-odata-v3-is-live.aspx" target="_blank">http://blogs.msdn.com/b/writingdata_services/archive/2011/03/09/march-2011-ctp-of-wcf-data-services-for-odata-v3-is-live.aspx</a>).</p> <p>Per eseguire qualche test, partiamo da un’applicazione ASP.NET vuota, alla quale aggiungiamo una classe C# con la definizione del modello dati, una biblioteca, composta dalle entità “Book” ed “Author”, ogni “Author” ha una relazione <em>one-to-many</em> con “Book”. Tradotto in codice:</p> <div id="codeSnippetWrapper"> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Book<br />{<br /> [Key] <br /> <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; }<br /> [Required]<br /> [MaxLength (80)]<br /> <span class="kwrd">public</span> <span class="kwrd">string</span> Title { get; set; }<br /> [Required]<br /> <span class="kwrd">public</span> <span class="kwrd">string</span> Summary { get; set; }<br />}<br /><br /><span class="kwrd">public</span> <span class="kwrd">class</span> Author<br />{<br /> [Key]<br /> <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; }<br /> [Required]<br /> <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; }<br /><br /> <span class="kwrd">public</span> <span class="kwrd">virtual</span> ICollection&lt;Book&gt; Books { get; set; }<br />}</pre> <br /></div> Generalmente preferisco utilizzare le Fluent API rispetto alle DateAnnotations, ma essendo un modello veramente semplice…va bene lo stesso <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WCF-Data-Service-CTP2--EF-4.1_FAD2/wlEmoticon-smile_2.png" />. Definiamo il <em>DbContext </em>in questo modo:</div> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> LibraryContext : DbContext<br />{<br /> <span class="kwrd">public</span> DbSet&lt;Book&gt; Books { get; set; }<br /> <span class="kwrd">public</span> DbSet&lt;Author&gt; Authors { get; set; } <br />}</pre> </div> <div>A questo punto aggiungiamo un WCF Data Service al progetto Web:</div> <div> </div> <div><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WCF-Data-Service-CTP2--EF-4.1_FAD2/image_2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WCF-Data-Service-CTP2--EF-4.1_FAD2/image_thumb.png" width="377" height="214" /></a></div> <div> </div> <div>Rinominiamolo in <em>LibraryService.svc. </em>Per utilizzare la versione CTP 2 è necessario eliminare i riferimenti alle librerie <em>System.Data.Services</em> e <em>System.Data.Services.Client</em> ed aggiungere i riferimenti alle librerie <em>Microsoft.Data.Services</em> e <em>Microsoft.Data.Services.Client </em>presenti nella directory <em>Bin </em>presente nel percorso di installazione della versione di WCF Data Service appena installata. Dovremmo ottenere qualcosa del genere:</div> <div><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WCF-Data-Service-CTP2--EF-4.1_FAD2/image_4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WCF-Data-Service-CTP2--EF-4.1_FAD2/image_thumb_1.png" width="281" height="125" /></a></div> <div>Oltre alle altre <em>References</em>. Modifichiamo il codice della classe <em>LibraryService </em>in questo modo:</div> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> LibraryService : DataService&lt;LibraryContext&gt;<br />{<br /> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> InitializeService(DataServiceConfiguration config)<br /> {<br /> config.SetEntitySetAccessRule(<span class="str">"Books"</span>, EntitySetRights.All );<br /> config.SetEntitySetAccessRule(<span class="str">"Authors"</span>, EntitySetRights.All);<br /> config.SetServiceOperationAccessRule(<span class="str">"FindBooksByTitle"</span>, ServiceOperationRights.AllRead);<br /> config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;<br /> }<br /><br /> [WebGet]<br /> <span class="kwrd">public</span> IQueryable&lt;Book&gt; FindBooksByTitle(<span class="kwrd">string</span> title)<br /> {<br /> <span class="kwrd">return</span> (from b <span class="kwrd">in</span> CurrentDataSource.Books <span class="kwrd">where</span> b.Title.Contains(title) select b);<br /> }<br />}</pre> </div> <p>Dove utilizziamo direttamente la nostra classe LibraryContext senza strane alchimie (override). Tramite l’<em>InitializeService</em> configuriamo il servizio per l’accesso alle entità “Books” ed “Authors”, configuriamo la versione del protocollo da utilizzare (<em>DataServiceProtocolVersion.V3</em>) e l’accesso a <em>FindBooksByTitle  </em>che permette di trovare tutti i libri che contengono un determinato titolo. Se utilizziamo del codice simile al seguente per creare e popolare la base dati sottostante: </p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode">Book book1 = <span class="kwrd">new</span> Book()<br />{<br /> Title = <span class="str">"Programming .Net 4 in C#"</span>,<br /> Summary = <span class="str">"Progamming .Net Framework 4 Book (C#)"</span><br />};<br /><br />Book book2 = <span class="kwrd">new</span> Book()<br />{<br /> Title = <span class="str">"Programming .Net 4 in VB.NET"</span>,<br /> Summary = <span class="str">"Progamming .Net Framework 4 Book (VB.NET)"</span><br />};<br /><br />Author author = <span class="kwrd">new</span> Author()<br />{<br /> Name=<span class="str">"Tizio Caio"</span><br />};<br /><br />author.Books = <span class="kwrd">new</span> List&lt;Book&gt;();<br />author.Books.Add(book1);<br />author.Books.Add(book2);<br /><br />cnt.Books.Add(book1);<br />cnt.Authors.Add(author);<br /><br />cnt.SaveChanges();</pre></div> <p>Possiamo avviare il sito tramite il Server Web locale ed utilizzare direttamente il browser per interagire con il servizio. Ad esempio possiamo recuperare la lista dei “Book” presenti digitando: <a href="http://localhost:5104/LibraryService.svc/Books">http://localhost:5104/LibraryService.svc/Books</a> o visualizzare i <em>metadata </em>esposti digitando <a title="http://localhost:5104/LibraryService.svc/$metadata" href="http://localhost:5104/LibraryService.svc/$metadata">http://localhost:5104/LibraryService.svc/$metadata</a>. Passiamo a qualcosa di più concreto aggiungendo un’applicazione console alla nostra soluzione, creando un riferimento al servizio tramite la voce di menu “Add Service Reference”. Visual Studio crea per noi tutte le classi proxy necessarie ed un file <em>Service.edmx</em> con la definizione del modello. Testiamo il tutto aggiungendo del codice nel <em>Main</em> della classe <em>Program</em>:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode">LibraryServiceReference.LibraryContext ctx = <span class="kwrd">new</span> LibraryServiceReference.LibraryContext(<span class="kwrd">new</span> Uri(<span class="str">"http://localhost:5104/LibraryService.svc/"</span>));<br /><br /> <span class="preproc">#region</span> Add Book and Author<br /><br /> Book book = <span class="kwrd">new</span> Book { Title = <span class="str">"Programming C# 4"</span>, Summary = <span class="str">"aaa"</span> };<br /> Author author = <span class="kwrd">new</span> Author { Name = <span class="str">"Tizio Caio"</span> };<br /><br /> author.Books.Add(book);<br /><br /> ctx.AddToBooks(book);<br /> ctx.AddToAuthors(author);<br /><br /> ctx.AddLink(author, <span class="str">"Books"</span>, book);<br /><br /> ctx.SaveChanges();<br /><br /> Console.WriteLine(ctx.Books.Count());<br /><br /> <span class="preproc">#endregion</span><br /><br /> <span class="preproc">#region</span> Update Book Title<br /><br /> book.Title = <span class="str">"Programming .NET 4 in C#"</span>;<br /> ctx.UpdateObject(book);<br /> ctx.SaveChanges();<br /><br /> Book storedBook = ctx.Books.Where(p =&gt; p.Id == book.Id).Select(p =&gt; p).FirstOrDefault();<br /><br /> Console.WriteLine(<span class="str">"Book Title={0}"</span>, book.Title);<br /><br /> <span class="preproc">#endregion</span><br /><br /> <span class="preproc">#region</span> Delete Book-Author link<br /><br /> Author storedAuthor = (from a <span class="kwrd">in</span> ctx.Authors.Expand(<span class="str">"Books"</span>)<br /> <span class="kwrd">where</span> a.Name.Equals(<span class="str">"Tizio Caio"</span>)<br /> select a)<br /> .FirstOrDefault();<br /><br /> Console.WriteLine(<span class="str">"Author={0}, Book Title={1}"</span>,storedAuthor.Name , storedAuthor.Books[0].Title);<br /><br /> <span class="rem">////Delete Link. Set null value in author_id column (Books Table).</span><br /> ctx.DeleteLink(storedAuthor, <span class="str">"Books"</span>, storedAuthor.Books[0]);<br /><br /> ctx.SaveChanges();<br /><br /> <span class="preproc">#endregion</span><br /></pre></div> <p>Il codice interagisce con un’istanza della <em>LibraryContext</em> sottostante per Aggiungere\Modificare\Eliminare i dati presenti nella base dati. Se volessimo interagire tramite <em>HTTPWebRequest</em>, potremmo scrivere del codice simile al seguente:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="preproc">#region</span> HttpWebRequest<br /><br /><span class="rem">////Get all Books</span><br />HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(<span class="kwrd">new</span> Uri(<span class="str">"http://localhost:5104/LibraryService.svc/Books"</span>));<br />webRequest.Method = <span class="str">"GET"</span>;<br />webRequest.Accept = <span class="str">"application/json"</span>;<br />HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();<br />System.IO.StreamReader streamReader = <span class="kwrd">new</span> System.IO.StreamReader(webResponse.GetResponseStream());<br /><br /><span class="kwrd">string</span> jSONResponse = streamReader.ReadToEnd();<br />Console.WriteLine(jSONResponse);<br /><br /><span class="rem">////Find Books by title.</span><br />webRequest = (HttpWebRequest)HttpWebRequest.Create(<span class="kwrd">new</span> Uri(<span class="str">"http://localhost:5104/LibraryService.svc/FindBooksByTitle?title='Programming'"</span>));<br />webRequest.Method = <span class="str">"GET"</span>;<br />webRequest.Accept = <span class="str">"application/json"</span>;<br />webResponse = (HttpWebResponse)webRequest.GetResponse();<br />streamReader = <span class="kwrd">new</span> System.IO.StreamReader(webResponse.GetResponseStream());<br /><br />jSONResponse = streamReader.ReadToEnd();<br />Console.WriteLine(jSONResponse);<br /><br /><span class="preproc">#endregion</span><br /><br /><span class="preproc">#region</span> Delete all objects<br /><br /><span class="rem">////Delete Objects.</span><br />ctx.DeleteObject(author);<br />ctx.DeleteObject(book);<br />ctx.SaveChanges();<br /><br /><span class="preproc">#endregion</span></pre> In entrambi i casi i dati vengono restituiti in formato JSON, quindi facilmente <em>parsabili</em>. Possiamo verificare come le nostre query LINQ siano tradotte in chiamate HTTP gestendo l’evento <em>SendingRequest</em> del servizio:</div> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">static</span> <span class="kwrd">void</span> ctx_SendingRequest(<span class="kwrd">object</span> sender, System.Data.Services.Client.SendingRequestEventArgs e)<br />{<br /> Console.WriteLine(e.Request.RequestUri.ToString());<br />}</pre> </div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100037.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/05/15/wcf-data-service-ctp2-e-ef-4.1.aspx Sun, 15 May 2011 20:55:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/05/15/wcf-data-service-ctp2-e-ef-4.1.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100037.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100037.aspx