<?xml version="1.0" encoding="iso-8859-15"?><feed version="0.3" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns="http://purl.org/atom/ns#" xml:lang="it-it"><title>AZ - Il blog di Andrea Zani</title><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/" /><tagline type="text/html">AZ - Il blog di Andrea Zani</tagline><id>http://blogs.aspitalia.com/az/</id><generator url="http://feed.aspitalia.com/" version="ASPItalia.com">feed.ASPItalia.com 'Weyoh' 4.8.828</generator><author><name>AZ - Il blog di Andrea Zani</name><url>http://blogs.aspitalia.com/az/</url></author><modified>2008-08-28T07:12:13+00:00</modified><entry><title>L'entity Framework e i vincoli FOREIGN KEY</title><id>http://blogs.aspitalia.com/az/post2374/Lentity-Framework-Vincoli-FOREIGN-KEY.aspx</id><created>2008-08-28T07:12:13+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2374' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;L'&lt;em&gt;entity framework&lt;/em&gt; rende felice. Ti fa vedere il mondo dei database sotto un'altra ottica. Le complicazioni create dai soliti esperti di struttura dei database fanno ora sorridere, anzi, li si incita a complicare maggiormente la struttura delle tabella per normalizzazioni fino al quinto livello.&lt;/p&gt; &lt;p&gt;-&lt;em&gt; Il terzo livello basta! &lt;br /&gt;&lt;/em&gt;- &lt;em&gt;No, andiamo fino al quinti livello di normalizzazione!&lt;/em&gt; - possono ora affermare i &lt;em&gt;dev &lt;/em&gt;sorseggiando un caff&amp;#232; alle loro spalle.&lt;/p&gt; &lt;p&gt;A parte queste &lt;em&gt;ciance&lt;/em&gt;, una delle attenzioni che si devono avere quando si usa l'&lt;em&gt;Entity Framework&lt;/em&gt; &amp;#232; quando si cancellano delle &lt;em&gt;entity&lt;/em&gt; dal database quando sono in gioco &lt;em&gt;Foreign key&lt;/em&gt; e amenit&amp;#224; simili. Inoltre, la cancellazione di una entit&amp;#224; non elimina - giustamente - di suo eventuali propriet&amp;#224; collegate uno-a-uno con un'altra tabella (sempre che sul db non ci siano regole varie, ma in questo caso di deve prestare attenzione, perch&amp;#233; la cache interna dell'&lt;em&gt;Entity Framework&lt;/em&gt; la vedr&amp;#224; ancora presente). Buona regola, nel caso di voler cancellare tutti i record coinvolti in una entit&amp;#224;, scrivere:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var padre = context.Canc_Padre.Include(&amp;quot;Canc_Figlia&amp;quot;).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var figlia = padre.Canc_Figlia; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.DeleteObject(figlia); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.DeleteObject(padre); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt; &lt;p&gt;In questo caso le tabelle di chiamano &lt;em&gt;Canc&lt;/em&gt;_&lt;em&gt;Padre&lt;/em&gt; e &lt;em&gt;Canc&lt;/em&gt;_&lt;em&gt;Figlia&lt;/em&gt;. L'ordine di cancellazione dev'essere anche quello mostrato (prima la tabella figlia e poi la padre), perch&amp;#233; la cancellazione dell'entit&amp;#224; padre farebbe perdere il collegamento con il record da cancellare con la necessit&amp;#224; di una nuova query di &lt;em&gt;select&lt;/em&gt; di ricerca. &lt;/p&gt; &lt;p&gt;Ma nel caso delle relazioni molti-a-molti? Prendiamo d'esempio un classico schema con tre tabelle: &lt;/p&gt; &lt;ol&gt; &lt;li&gt;authors &lt;/li&gt; &lt;li&gt;books &lt;/li&gt; &lt;li&gt;authorsbooks&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Le prime due sono le classiche tabelle che conterranno i dati, la terza quella che collega i dati delle due.&lt;/p&gt; &lt;p&gt;Scrivendo questo codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var coll = (from au in context.authors &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; where au.name==&amp;quot;...&amp;quot; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select au).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.DeleteObject(coll); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Otterremo il classico errore:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;L'istruzione DELETE &amp;#232; in conflitto con il vincolo REFERENCE &amp;quot;FK_authors_books_authors&amp;quot;. Il conflitto si &amp;#232; verificato nella tabella &amp;quot;dbo.authorsbooks&amp;quot;, column 'id_author' del database &amp;quot;pubs&amp;quot;.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Per evitare questo problema, cio&amp;#232; cancellare il record dalla tabella &lt;em&gt;authors&lt;/em&gt; e ogni suo riferimento dalla tabella &lt;em&gt;authorsbooks&lt;/em&gt;, dovremo invece scrivere:&lt;/p&gt; &lt;em&gt;using (pubsModel.pubsEntities2 context = new pubsModel.pubsEntities2()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var coll = (from au in context.authors.&lt;strong&gt;Include(&amp;quot;books&amp;quot;)&lt;/strong&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; where au.name==&amp;quot;...&amp;quot; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select au).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.DeleteObject(coll); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;} &lt;/em&gt; &lt;p&gt;Se volessimo cancellare anche il record in &lt;em&gt;book&lt;/em&gt;, dovremo fare come sopra: recuperata l'&lt;em&gt;entity&lt;/em&gt; usare il &lt;em&gt;DeleteObject&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;PS: ieri sera ho dovuto aspettare venti minuti il pullman per tornare a casa.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Database/&quot; rel=&quot;tag&quot;&gt;Database&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2374/Lentity-Framework-Vincoli-FOREIGN-KEY.aspx"/><issued>2008-08-28T09:12:13+00:00</issued><modified>2008-08-28T09:12:13+00:00</modified><slash:comments>6</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2374/Lentity-Framework-Vincoli-FOREIGN-KEY.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2374.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2374</trackback:ping></entry><entry><title>Data Service Viewer</title><id>http://blogs.aspitalia.com/az/post2373/Data-Service-Viewer.aspx</id><created>2008-08-28T07:09:20+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2373' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Interessante questo &lt;a title=&quot;link esterno&quot; href=&quot;http://weblogs.asp.net/vardi/archive/2008/08/27/ado-net-data-services-viewer-tool.aspx&quot;&gt;tool&lt;/a&gt;. Anche se &lt;a title=&quot;link esterno&quot; href=&quot;http://astoria.mslivelabs.com/&quot;&gt;Astoria&lt;/a&gt; &amp;#232; una tecnologia che mi mette parecchi dubbi (dubbi che non voglio per ora divulgare qui) la trovo interessante. E se c'&amp;#232; un tool che permette di provare le richieste http in modo facile e che ti d&amp;#224; anche una mano, ben venga.&lt;/p&gt; &lt;p&gt;E' un exe scritto in .net. Alla prima richiesta richiede l'endpoint dove astoria &amp;#232; in attesa, per esempio:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://localhost:1035/websiteentity2/webdataservice.svc&quot;&gt;http://localhost:1035/WebSiteEntity2/WebDataService.svc&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Nel codice di questo &lt;em&gt;ado.net web data service&lt;/em&gt;, &amp;#232; necessario obbligare quali entit&amp;#224; possono essere utilizzate e come:&lt;/p&gt; &lt;p&gt;&lt;em&gt;public class WebDataService : DataService&amp;lt;pubsModel.pubsEntities2&amp;gt; &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static void InitializeService(IDataServiceConfiguration config) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; config.SetEntitySetAccessRule(&amp;quot;*&amp;quot;, EntitySetRights.All); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; config.SetServiceOperationAccessRule(&amp;quot;*&amp;quot;, ServiceOperationRights.All); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;}&lt;/em&gt; &lt;/p&gt; &lt;p&gt;Qui ho specificato che &amp;#232; possibile operare su tutte le entit&amp;#224; e che posso farci di tutto tra queste scelte possibili.&lt;/p&gt; &lt;p&gt;Ok, avviata la web application con questo nuovo oggetto, possiamo utilizzare il tool prima citato che il nome significativo &amp;quot;Data service viewer&amp;quot;. Inserito l'endpoint, ecco la schermata:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;459&quot; alt=&quot;data service viewer&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%202_3.gif&quot; width=&quot;524&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;Ma l'utilit&amp;#224; vera &amp;#232; nella possibilit&amp;#224; di provare le query avendo il supporto per l'intellisense durante la scrittura:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%201_2.gif&quot;&gt;&lt;img height=&quot;388&quot; alt=&quot;data service viewer&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%201_thumb.gif&quot; width=&quot;523&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Qui si scopre un piccolo problema. L'elenco delle scelte possibile &amp;#232; selezionabile con i tasti cursore e la scelta &amp;#232; selezionabile solo con il tasto invio e con il mouse mentre il tasto tab manda al pulsante per l'esecuzione della query.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2373/Data-Service-Viewer.aspx"/><issued>2008-08-28T09:09:20+00:00</issued><modified>2008-08-28T09:09:20+00:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2373/Data-Service-Viewer.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2373.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2373</trackback:ping></entry><entry><title>Lazy Loading con l'Entity Framework</title><id>http://blogs.aspitalia.com/az/post2372/Lazy-Loading-Entity-Framework.aspx</id><created>2008-08-27T11:33:57+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2372' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Anche se qualcuno afferma il contrario, non cito la fonte, abbiamo a disposizione pi&amp;#249; metodi per caricare entit&amp;#224; collegate. In tutti questi post dedicati all'&lt;em&gt;Entity Framework&lt;/em&gt; ho fatto sempre esempio che riguardavano pi&amp;#249; tabelle (~entit&amp;#224;) collegate.&lt;/p&gt; &lt;p&gt;Possiamo fare in modo che sia lo stesso &lt;em&gt;Entity Framework&lt;/em&gt; a caricare con una query il tutto grazie a Include:&lt;/p&gt; &lt;p&gt;&lt;em&gt;var coll=from c in EntityContext.Articles.Include(&amp;quot;Authors&amp;quot;) &lt;br /&gt;select c; &lt;br /&gt;foreach (var item in coll) &lt;br /&gt;{ &lt;br /&gt;Response.Write(item.Title); &lt;br /&gt;Response.Write(item.Authors.Name); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Oppure possiamo forzare il caricamente delle entit&amp;#224; collegate, in questo caso &lt;em&gt;Authors&lt;/em&gt;, ad ogni richiesta della stessa:&lt;/p&gt; &lt;p&gt;&lt;em&gt;var coll=from c in EntityContext.Articles &lt;br /&gt;select c; &lt;br /&gt;foreach (var item in coll) &lt;br /&gt;{ &lt;br /&gt;Response.Write(item.Title); &lt;br /&gt;if (item.AuthorsReference.IsLoaded) // Controlla se gi&amp;#224; presente in memoria &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Response.Write(item.AuthorsReference.Value.Name); &lt;br /&gt;else &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; item.AuthorsReference.Load(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Response.Write(item.Authors.Name); &lt;br /&gt;} &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;In quest'ultimo caso all'inizio viene eseguita una query che richiede solo la lista degli &lt;em&gt;Articles&lt;/em&gt;. Quindi viene verificato che l'entit&amp;#224; per gli &lt;em&gt;Authors&lt;/em&gt; non sia gi&amp;#224; presente in memoria; se presente la visualizza direttamente, altrimenti esegue una query al database.&lt;/p&gt; &lt;p&gt;Il numero di query inviate al database &amp;#232; N+(numero di autori richiesti differenti). Ipoteticamente, se tutti gli articoli fossero collegati ad un solo autore, il numero di query inviate al database sarebbero due.&lt;/p&gt; &lt;p&gt;PS: scusate la brevit&amp;#224; ma il tempo &amp;#232; tiranno. O Tir&lt;em&gt;&amp;#224;&lt;/em&gt;no?&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2372/Lazy-Loading-Entity-Framework.aspx"/><issued>2008-08-27T13:33:57+00:00</issued><modified>2008-08-27T13:33:57+00:00</modified><slash:comments>6</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2372/Lazy-Loading-Entity-Framework.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2372.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2372</trackback:ping></entry><entry><title>4 desktop virtuali su Windows</title><id>http://blogs.aspitalia.com/az/post2371/Desktop-Virtuali-Windows.aspx</id><created>2008-08-26T12:01:02+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2371' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Una peculiarit&amp;#224; che ho sempre apprezzato nei desktop manager di Linux &amp;#232; la possibilit&amp;#224; di dividere la zona di lavoro su pi&amp;#249; desktop virtuali. &lt;a title=&quot;link esterno&quot; href=&quot;http://blogs.dotnethell.it/windowsvista/post_14028.aspx&quot;&gt;Leggo&lt;/a&gt; ora che &amp;#232; presente questo &lt;a title=&quot;link esterno&quot; href=&quot;http://technet.microsoft.com/en-us/sysinternals/cc817881.aspx&quot;&gt;tool&lt;/a&gt; che lo permette anche su Windows. Scaricato e avviato. Funziona discretamente, ed &amp;#232; veloce e &lt;em&gt;pesa&lt;/em&gt; poco. Il problema &amp;#232; un altro: non permette i passaggi di finestre tra un desktop all'altro con la stessa facilit&amp;#224; che permette Gnome o Kde: vengono s&amp;#236; create pi&amp;#249; arie di lavoro, ma queste non sembrano poter comunicare.&lt;/p&gt; &lt;p&gt;Peccato.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2371/Desktop-Virtuali-Windows.aspx"/><issued>2008-08-26T14:01:02+00:00</issued><modified>2008-08-26T14:01:02+00:00</modified><slash:comments>9</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2371/Desktop-Virtuali-Windows.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2371.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2371</trackback:ping></entry><entry><title>A volte ritornano... GridView vs Repeater vs ListView vs Custom</title><id>http://blogs.aspitalia.com/az/post2370/Volte-Ritornano.-GridView-Repeater-ListView-Custom.aspx</id><created>2008-08-26T07:20:37+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2370' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/az/post549/ancora-prestazioni-datagrid-datalist-repeater-.aspx&quot;&gt;Sono passati anni&lt;/a&gt;? Parecchio tempo fa avevo confrontato le prestazioni nel binding dei dati tra i pi&amp;#249; noti webcontrol. Ecco un refresh, questa volta con il Framework 3.5 e con lo scontro tra:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Gridview &lt;/li&gt; &lt;li&gt;Repeater &lt;/li&gt; &lt;li&gt;ListView &lt;/li&gt; &lt;li&gt;Custom code&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Chiunque un po' smaliziato con il .net sapr&amp;#224; gi&amp;#224; chi vince e chi &amp;#232; il peggiore tra questi. Ma per i novizi &amp;#232; sempre meglio saperlo. Innanzitutto, il codice per il popolamento delle tabelle html &amp;#232; il seguente:&lt;/p&gt; &lt;p&gt;&lt;em&gt;List&amp;lt;Person&amp;gt; p; &lt;br /&gt;p = new List&amp;lt;Person&amp;gt;(200); &lt;br /&gt;for (int i = 0; i &amp;lt; 200; i++) &lt;br /&gt;&amp;#160; p.Add(new Person { Id=i, Age=i, Description=&amp;quot;Desc &amp;quot;+i.ToString(), Name=&amp;quot;Name &amp;quot;+i.ToString() }); &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Il &lt;em&gt;gridview&lt;/em&gt; crea la table html con questo codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;asp:GridView ID=&amp;quot;gw1&amp;quot; EnableViewState=&amp;quot;false&amp;quot; runat=&amp;quot;server&amp;quot; AutoGenerateColumns=&amp;quot;false&amp;quot;&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Columns&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:BoundField DataField=&amp;quot;id&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:BoundField DataField=&amp;quot;name&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:BoundField DataField=&amp;quot;age&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:BoundField DataField=&amp;quot;description&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Columns&amp;gt; &lt;br /&gt;&amp;lt;/asp:GridView&amp;gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Per il &lt;em&gt;repeater&lt;/em&gt; abbiamo: &lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;asp:Repeater ID=&amp;quot;rp1&amp;quot; runat=&amp;quot;server&amp;quot; EnableViewState=&amp;quot;false&amp;quot;&amp;gt; &lt;br /&gt;&amp;lt;HeaderTemplate&amp;gt;&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;/HeaderTemplate&amp;gt; &lt;br /&gt;&amp;lt;FooterTemplate&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/FooterTemplate&amp;gt; &lt;br /&gt;&amp;lt;ItemTemplate&amp;gt; &lt;br /&gt;&amp;lt;tr&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;id&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;name&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;age&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;description&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;lt;/tr&amp;gt; &lt;br /&gt;&amp;lt;/ItemTemplate&amp;gt; &lt;br /&gt;&amp;lt;/asp:Repeater&amp;gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;M&lt;/em&gt;a siccome vogliamo ottimizzare un po', possiamo scrivere: &lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;tr&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Id %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Name %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Age %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Description %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;lt;/tr&amp;gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Ecco il &lt;em&gt;ListView&lt;/em&gt;, semplice: &lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;asp:ListView ID=&amp;quot;lw1&amp;quot; runat=&amp;quot;server&amp;quot; EnableViewState=&amp;quot;false&amp;quot;&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;LayoutTemplate&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;asp:Panel ID=&amp;quot;itemPlaceholder&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/table&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/LayoutTemplate&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ItemTemplate&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;id&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;name&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;age&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# Eval(&amp;quot;description&amp;quot;) %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ItemTemplate&amp;gt; &lt;br /&gt;&amp;lt;/asp:ListView&amp;gt;&lt;/em&gt;&amp;#160;&lt;/p&gt; &lt;p&gt;E ottimizzato: &lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;ItemTemplate&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Id %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Name %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Age %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;%# ((Person)Container.DataItem).Description %&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt; &lt;br /&gt;&amp;lt;/ItemTemplate&amp;gt; &lt;/em&gt;&lt;/p&gt; &lt;p&gt;E infine creiamo la griglia da codice con un banale &lt;em&gt;StringBuilder&lt;/em&gt; da codice: &lt;/p&gt; &lt;p&gt;&lt;em&gt;var sb = new StringBuilder(10000); &lt;br /&gt;sb.Append(&amp;quot;&amp;lt;table border='1'&amp;gt;&amp;quot;); &lt;br /&gt;for (int i = 0; i &amp;lt; p.Count; i++) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(p[i].Id); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(p[i].Name); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(p[i].Age); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(p[i].Description); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sb.Append(&amp;quot;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;); &lt;br /&gt;} &lt;br /&gt;sb.Append(&amp;quot;&amp;lt;/table&amp;gt;&amp;quot;); &lt;br /&gt;pn1.Controls.Add(new LiteralControl(sb.ToString())); &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;pn1&lt;/em&gt; &amp;#232; un &lt;em&gt;panel&lt;/em&gt;. Ma vediamo le prestazioni (medie): &lt;/p&gt; &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot; border=&quot;1&quot;&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;GridView&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;strong&gt;&lt;em&gt;0.122s&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;Repeater&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;0.058s&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;Repeater ottimizzato&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;0.046s&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;ListView&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;0.059s&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;ListView ottimizzato&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;0.047s&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;Custom code&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;&lt;em&gt;&lt;strong&gt;0.006s&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;A parte la tabella scritta con lo &lt;em&gt;StringBuilder&lt;/em&gt; che mediamente risulta otto volte pi&amp;#249; veloce del &lt;em&gt;ListView&lt;/em&gt; e del &lt;em&gt;Repeater&lt;/em&gt;, la sorpresa &amp;#232; proprio il &lt;em&gt;ListView&lt;/em&gt; che risulta veloce quanto il &lt;em&gt;Repeater&lt;/em&gt;. In poche parole? Il &lt;em&gt;DataGrid&lt;/em&gt;, &lt;em&gt;DataList&lt;/em&gt;, &lt;em&gt;DataGrid&lt;/em&gt; e &lt;em&gt;Repeater&lt;/em&gt; sono diventati obsoleti e inutili dato il &lt;em&gt;ListView&lt;/em&gt; non solo sostituisce in tutto questi webcontrol, ma ha prestazioni pi&amp;#249; che buone.&amp;#160;&amp;#160; &lt;/p&gt; &lt;p&gt;Inoltre, per avere un discreto guadagno, anche la visualizzazione con il &lt;em&gt;casting&lt;/em&gt; di tipo nella colonna, invece dell'&lt;em&gt;Eval&lt;/em&gt;, &amp;#232; consigliato.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/ASP.NET/&quot; rel=&quot;tag&quot;&gt;ASP.NET&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/ASP.NET_2.0/&quot; rel=&quot;tag&quot;&gt;ASP.NET 2.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/ASP.NET_3.5/&quot; rel=&quot;tag&quot;&gt;ASP.NET 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Databinding/&quot; rel=&quot;tag&quot;&gt;Databinding&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Datagrid/&quot; rel=&quot;tag&quot;&gt;Datagrid&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/GridView/&quot; rel=&quot;tag&quot;&gt;GridView&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2370/Volte-Ritornano.-GridView-Repeater-ListView-Custom.aspx"/><issued>2008-08-26T09:20:37+00:00</issued><modified>2008-08-26T09:20:37+00:00</modified><slash:comments>15</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2370/Volte-Ritornano.-GridView-Repeater-ListView-Custom.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2370.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2370</trackback:ping></entry><entry><title>L'Entity Framework e l'ObjectDataSource</title><id>http://blogs.aspitalia.com/az/post2369/LEntity-Framework-ObjectDataSource.aspx</id><created>2008-08-24T19:26:00+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2369' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Anche se con l'SP1 del Framework 3.5 &#232; stato introdotto il nuovo &lt;em&gt;EntityDataSource&lt;/em&gt; per collegare direttamente questi nuovi oggetti a web control come il &lt;em&gt;ListView&lt;/em&gt; o il &lt;em&gt;GridView&lt;/em&gt;, l'utilizzo dell'&lt;em&gt;ObjectDataSource&lt;/em&gt; rimane sempre la soluzione migliore: come dice &lt;a href=&quot;http://blogs.aspitalia.com/daniele&quot;&gt;Daniele&lt;/a&gt;, i &lt;em&gt;datasource&lt;/em&gt; come l'&lt;em&gt;SqlDataSource&lt;/em&gt; e compagnia bella sono solo veramente utili per le demo.&lt;/p&gt;&lt;p&gt;Di base non ci sono problemi. Solo di base per&#242;. Quando si cerca di fare qualcosa di pi&#249; complesso saltano sempre fuori casini vari. Messo nella pagina un &lt;em&gt;ListView&lt;/em&gt; collegato ad un bel &lt;em&gt;ObjectDataSource&lt;/em&gt; che utilizza una classe apposita che ritorna le entit&#224; (nel mio caso con l'ausilio dell'&lt;em&gt;Entity Framework&lt;/em&gt;) non ci sono problemi: persino altre entit&#224; memorizzate in propriet&#224; vengono visualizzate correttamente. Come nell'esempio gi&#224; &lt;a href=&quot;http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx&quot;&gt;visto&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;gridview&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_1.png&quot; /&gt; &lt;/p&gt;&lt;p&gt;I problemi nascono quando entrano in gioco gli update e gli insert. Come scritto sopra, di base, cio&#232; con propriet&#224; con tipi non complessi, non ci sono problemi. Definendo nell'&lt;em&gt;InsertMethod&lt;/em&gt; dell'&lt;em&gt;ObjectDataSource&lt;/em&gt; una nostra funzione come la seguente, tutto funziona:&lt;/p&gt;&lt;p&gt;&lt;em&gt;[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]&lt;br /&gt;public static void InsertAuthor(Author author)&lt;br /&gt;{&lt;br /&gt;using (TestEntitiesModel.TestEntitiesCode context = new TestEntitiesModel.TestEntitiesCode())&lt;br /&gt;{&lt;br /&gt;context.addAuthors(author);&lt;br /&gt;context.SaveChanges();&lt;br /&gt;} &lt;br /&gt;}&lt;/em&gt; &lt;/p&gt;&lt;p&gt;Che bello! Eh s&#236;, ma l'entit&#224; qui trattata ha anche come propriet&#224; la collection di &lt;em&gt;Book&lt;/em&gt; collegati all'autore secondo il seguente schema: &lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;entity framework&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_6.png&quot; /&gt; &lt;/p&gt;&lt;p&gt;Per visualizzare il tutto in modalit&#224; &lt;em&gt;edit&lt;/em&gt; si incotrano le prime rogne ma risolvibile. Ma cosa viene passato al metodo &lt;em&gt;InsertAuthor&lt;/em&gt; prima mostrato? Tutto, tranne, ovviamente, eventuli aggiunte ai &lt;em&gt;book&lt;/em&gt;. Qui l'esempio &#232; un po' forzato, ma un caso reale potrebbe essere la creazione di un nuovo utente e il collegamento ad esso di una o pi&#249; role per autorizzazione varie (visualizzate in modalit&#224; &lt;em&gt;edit&lt;/em&gt; come lista con &lt;em&gt;checkbox&lt;/em&gt;). &lt;/p&gt;&lt;p&gt;Come inviare il tutto in modo corretto a quella funzione o quasi? &lt;/p&gt;&lt;p&gt;Io ho solo trovato un espediente, ma spero ci siano soluzioni pi&#249; semplici che finora mi sono sfuggite. Utilizzando l'evento &lt;em&gt;On_ItemInserting&lt;/em&gt; dell'&lt;em&gt;ListView&lt;/em&gt; possiamo forza l'aggiunta di tutte le informazioni utili: &lt;/p&gt;&lt;p&gt;&lt;em&gt;protected void lw_authors_ItemInserting(object sender, ListViewInsertEventArgs e)&lt;br /&gt;{&lt;br /&gt;// In Values troviamo tutti i valori letti dal objectdatasource (BoundColumn, Bind, ecc...)&lt;br /&gt;// Inserisce un campo aggiuntivo perla data presente nel db ma non del ListView&lt;br /&gt;e.Values.Add(&amp;quot;CreationData&amp;quot;, DateTime.Now);&lt;br /&gt;var books = new System.Data.Objects.DataClasses.EntityCollection&lt;book /&gt;();&lt;br /&gt;// Metodi che richiedono le entit&#224; da collegare&lt;br /&gt;books.Add( AZ.GetBookFromId(1) );&lt;br /&gt;books.Add( AZ.GetBookFromId(2) );&lt;br /&gt;e.Values.Add(&amp;quot;Books&amp;quot;, auths);&lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;&lt;p&gt;Innanzitutto, l'&lt;em&gt;objectdatasource&lt;/em&gt; espone la connection come &lt;em&gt;EntityConnection&lt;/em&gt;, quindi perch&#233; possa essere riconosciuta dobbiamo inserire tutti gli item selezionati in questa collection. Sembra tutto ok, in questo modo all'evento di inserimento &lt;em&gt;dovrebbe&lt;/em&gt; essere passato il tutto correttamente. Dovrebbe! Richiamato questo codice si ha come output un errore chiarissimo in merito proprio al momento dell'&lt;em&gt;Add&lt;/em&gt;:&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;strong&gt;The object could not be added to the EntityCollection or EntityReference. An object that is attached to an ObjectContext cannot be added to an EntityCollection or EntityReference that is not associated with a source object.&lt;/strong&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Allora ecco l'&lt;em&gt;escamotage&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;protected void lw_users_ItemInserting(object sender, ListViewInsertEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var books = new System.Data.Objects.DataClasses.EntityCollection&amp;lt;Book&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; books.Add(new&amp;nbsp;Book { Id = 1 });&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; books.Add(new&amp;nbsp;Book { Id = 2 });&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Values.Add(&quot;Books&quot;, auths);&lt;br&gt;} &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Creo due nuove classi &lt;em&gt;Book&lt;/em&gt; dove inserisco gli &lt;em&gt;Id&lt;/em&gt; dei valori selezionati nell'interfaccia grafica (qui inseriti da codice per rendere il tutto pi&#249; semplice). Ora il codice per l'inserimento dovrebbe accettare anche questi dati aggiuntivi, ma ecco il secondo problema della giornata: quelle entit&#224; verrebbero trattate come nuovi oggetti e inseriti nuovamente nel database. Ecco dunque l'ultima modifica al codice, questa volta nella funzione di inserimento:&lt;/p&gt;&lt;em&gt;[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]&lt;br&gt;public static void InsertAuthor(Author author)&lt;br&gt;{&lt;br&gt;&amp;nbsp;using (TestEntitiesModel.TestEntitiesCode context = new TestEntitiesModel.TestEntitiesCode())&lt;br&gt;&amp;nbsp;{&lt;br&gt;&amp;nbsp; var coll = user.Books.Select(r =&amp;gt; r.Id).ToArray&amp;lt;int&amp;gt;();&lt;br&gt;&amp;nbsp; user.Books.Clear();&lt;br&gt;&amp;nbsp; foreach (var item in coll)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; user.Books.Add( context.Books.Where( r=&amp;gt;r.Id==item ).FirstOrDefault() );&lt;br&gt;&amp;nbsp; // Oppure&lt;br&gt;&amp;nbsp; // foreach (var item in coll)&lt;br&gt;&amp;nbsp;&amp;nbsp;//&amp;nbsp; user.Books.Add(&amp;nbsp;context.GetObjectbyKey( item ) );&lt;br&gt;&amp;nbsp;&amp;nbsp;context.addAuthors(author);&lt;br&gt;&amp;nbsp; context.SaveChanges();&lt;br&gt;&amp;nbsp;} &lt;br&gt;}&lt;/em&gt; 
&lt;p&gt;E tutto funziona correttamente. Ma spero ci siano soluzioni pi&#249; immediate e semplici. Vero? Ditemi di s&#236;! :(&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2369/LEntity-Framework-ObjectDataSource.aspx"/><issued>2008-08-24T21:26:00+00:00</issued><modified>2008-08-24T21:26:00+00:00</modified><slash:comments>15</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2369/LEntity-Framework-ObjectDataSource.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2369.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2369</trackback:ping></entry><entry><title>SP vs Linq vs Entity Framework in scrittura</title><id>http://blogs.aspitalia.com/az/post2368/SP-Linq-Entity-Framework-Scrittura.aspx</id><created>2008-08-22T21:11:44+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2368' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;La sola sicurezza che avevo era &lt;strong&gt;di quanto&lt;/strong&gt; Linq e l'Entity Framework fossero pi&#249; lenti. Mi preparo un banale test per l'inserimento di un buon numero di record in un database Sql server 2005 per un benchmark personale. Creo due tabelle collegate dalla struttura molto semplice:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;320&quot; alt=&quot;struttura tabelle&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_1.png&quot; width=&quot;358&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p&gt;Il mio test &#232; molto banale: creare un array casuale di 100 padri, e ogni padre un array casuale di 100 figli. Gli sfidanti e le armi utilizzate sono i seguenti:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Collection tradizionale e stored procedure (una per ogni tabella) richiamata con il &lt;em&gt;Prepare&lt;/em&gt; del &lt;em&gt;Command&lt;/em&gt; per il massimo delle prestazioni.&lt;/li&gt; &lt;li&gt;Collection inserita direttamente in un DataContext creato da Visual Studio 2008.&lt;/li&gt; &lt;li&gt;Collection inserita direttamente nelle collection create dall'Entity Framework.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Ecco di seguito il DataContext usato da Linq:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;298&quot; alt=&quot;datacontext di linq&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_3.png&quot; width=&quot;236&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p&gt;E l'&lt;em&gt;Entity Framework&lt;/em&gt; creato sempre da VS2008:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;352&quot; alt=&quot;l'entity framework creato da vs2008&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_5.png&quot; width=&quot;182&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p&gt; Avvio pi&#249; volte i test per ogni tecnologia utilizzata. La media &#232; la seguente:&lt;/p&gt; &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot; border=&quot;1&quot; unselectable=&quot;on&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width=&quot;133&quot;&gt;&lt;strong&gt;Stored procedure&lt;/strong&gt;&lt;/td&gt; &lt;td  width=&quot;133&quot;&gt;&lt;strong&gt;Linq to Sql&lt;/strong&gt;&lt;/td&gt; &lt;td  width=&quot;133&quot;&gt;&lt;strong&gt;Entity Framework&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;133&quot;&gt;6.75&lt;em&gt;s&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;133&quot;&gt;20.60&lt;em&gt;s&lt;/em&gt;&lt;/td&gt; &lt;td  width=&quot;133&quot;&gt;12.93&lt;em&gt;s&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Sulla maggiori performance dell'inserimento diretto da codice con le &lt;em&gt;stored procedure&lt;/em&gt;, come gi&#224; detto, non ne avevo il minimo dubbio: il tutto &#232; ottimizzato al meglio, ed ho cercato anche da codice di ottimizzare il pi&#249; possibile la creazione di oggetti e il passaggio di parametri. La delusione &#232; stata invece per Linq, che le prende sonoramente anche dall'&lt;em&gt;Entity Framework&lt;/em&gt; che si dimostra molto pi&#249; efficiente del tradizionale &lt;em&gt;Linq to Sql&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Leggendo con il Profiler le query inviate da &lt;em&gt;Linq to Sql&lt;/em&gt; e dall'&lt;em&gt;Entity Framework&lt;/em&gt;, si notano alcune differenze nelle query di inserimento create:&lt;/p&gt; &lt;p&gt;&lt;em&gt;-- Linq to Sql&lt;br /&gt;-- Inserimento nella tavella 'Padri'&lt;br /&gt;exec sp_executesql N'INSERT INTO [dbo].[Padri]([NomePadre])&lt;br /&gt;VALUES (@p0) &lt;br /&gt;SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]',N'@p0 nvarchar(7)',@p0=N'Padre 1'&lt;br /&gt;--&lt;br /&gt;-- Inserimento nella tabella 'Figli'&lt;br /&gt;exec sp_executesql N'INSERT INTO [dbo].[Figli]([IdPadre], [NomeFiglio])&lt;br /&gt;VALUES (@p0, @p1) &lt;br /&gt;SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]',N'@p0 int,@p1 nvarchar(9)',@p0=400,@p1=N'Padre 1 1'&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;---- Entity Framework&lt;br /&gt;-- Inserimenti nella tabella 'Padri'&lt;br /&gt;exec sp_executesql N'insert [dbo].[Padri]([NomePadre])&lt;br /&gt;values (@0)&lt;br /&gt;select [Id]&lt;br /&gt;from [dbo].[Padri]&lt;br /&gt;where @@ROWCOUNT &amp;gt; 0 and [Id] = scope_identity()',N'@0 nvarchar(7)',@0=N'Padre 1'&lt;br /&gt;--&lt;br /&gt;-- Inserimento nella tabella 'Figli'&lt;br /&gt;exec sp_executesql N'insert [dbo].[Figli]([IdPadre], [NomeFiglio])&lt;br /&gt;values (@0, @1)&lt;br /&gt;select [Id]&lt;br /&gt;from [dbo].[Figli]&lt;br /&gt;where @@ROWCOUNT &amp;gt; 0 and [Id] = scope_identity()',N'@0 int,@1 nvarchar(9)',@0=1600,@1=N'Padre 1 1'&lt;/em&gt;&lt;/p&gt; &lt;p&gt;La cosa che salta all'occhio subito &#232; il differente modo di prendere l'&lt;em&gt;id&lt;/em&gt; del record appena inserito e sembra, e lo ripeto, sembra, che sia pi&#249; performante quello utilizzato dall'Entity Framework anche se, la differenze in peggio tra le due tecnolgie, potrebbero essere invece a livello di codice del Framework nelle sue creazioni delle query.&lt;/p&gt; &lt;p&gt;Ora &#232; tardi per investigare oltre. Ho fatto appena un viaggio di circa tre ore di pullman e sono stanco... Ma prima, si possono tirare conclusioni? Il mio test pu&#242; essere un caso reale di codice? La stanchezza mi sta spegnendo la ragione... mi fermo qui&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/ADO.NET_Entity_Framework/&quot; rel=&quot;tag&quot;&gt;ADO.NET Entity Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Database/&quot; rel=&quot;tag&quot;&gt;Database&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2368/SP-Linq-Entity-Framework-Scrittura.aspx"/><issued>2008-08-22T23:11:44+00:00</issued><modified>2008-08-22T23:11:44+00:00</modified><slash:comments>9</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2368/SP-Linq-Entity-Framework-Scrittura.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2368.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2368</trackback:ping></entry><entry><title>Ho fatto pace con l'Entity Framework: un minimo di cache!</title><id>http://blogs.aspitalia.com/az/post2367/Fatto-Pace-Entity-Framework-Minimo-Cache.aspx</id><created>2008-08-22T12:26:34+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2367' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Nel &lt;a href=&quot;http://blogs.aspitalia.com/az/post2366/entity-framework.-minimo-cache-faceva-schifo.aspx&quot;&gt;post precedente&lt;/a&gt; riscontravo che come due richieste sulla stessa entit&amp;#224; venisse gestita dall'Entity Framework in maniera - per me - strana, o per meglio dire, non in modo ottimizzato, perch&amp;#233; eseguiva due query perfettamente identiche al database. Ovviamente, come mi ha fatto notare giustamente &lt;a href=&quot;http://blogs.aspitalia.com/daniele/&quot;&gt;Daniele&lt;/a&gt; e &lt;a href=&quot;http://blogs.aspitalia.com/ricciolo/&quot;&gt;Cristian&lt;/a&gt;, &amp;#232; un comportamento legittimo, e anzi, sarebbe stato strano se avveniva come io lo avevo immaginato.&lt;/p&gt; &lt;p&gt;Scopro solo ora che nativamente esiste una sorta di cache all'interno dell'Entity Framework, ma la cosa deve essere forzata dal programmatore. Riprendendo l'esempio del mio blog precedente, si deve scrivere:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestModel.TestEntities context = new TestModel.TestEntities()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int colore = 2; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art3 &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var c = context.Colors.Where(w =&amp;gt; w.Id == colore).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.AddToArticles(a); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art4 &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ////////////////////////////////////// &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; object obj = null; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.TryGetObjectByKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new System.Data.EntityKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string.Format(&amp;quot;{0}.{1}&amp;quot;, context.DefaultContainerName, &amp;quot;Colors&amp;quot;), &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Id&amp;quot;, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; colore), out obj); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (obj != null) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // E' presente tra gli oggetti &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c = (TestModel.Colors)obj; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Rifaccio la query (*) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c = context.Colors.Where(w =&amp;gt; w.Id == colore).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ///////////////////////////////////// &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.AddToArticles(a); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;A venirmi in aiuto ci pensa la funzione &lt;em&gt;TryGetObjectByKey&lt;/em&gt; che permette di cercare un oggetto per la sua &lt;em&gt;key&lt;/em&gt; all'interno del &lt;em&gt;context&lt;/em&gt; attuale utilizzato per l'&lt;em&gt;entity framework&lt;/em&gt;. La sintassi &amp;#232; un po' intricata, ma risolve un sacco di dubbi. Ora, avviando l'esempio con il &lt;em&gt;profiler&lt;/em&gt; avviato, vedo che viene eseguita una sola query per recuperare l'&lt;em&gt;entity&lt;/em&gt; del colore...&lt;/p&gt; &lt;p&gt;Ma il &lt;em&gt;TryGetObjectByKey&lt;/em&gt; non solo &amp;#232; in grado di prendere il valore se &amp;#232; gi&amp;#224; stata trattata, ma esegue lui stesso una query nel caso il valore non fosse presente. Il codice qui sopra potrebbe essere scritto in modo pi&amp;#249; semplice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestModel.TestEntities context = new TestModel.TestEntities()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int colore = 2; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art3 &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TestModel.Colors c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; object obj = null; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.TryGetObjectByKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new System.Data.EntityKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string.Format(&amp;quot;{0}.{1}&amp;quot;, context.DefaultContainerName, &amp;quot;Colors&amp;quot;), &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Id&amp;quot;, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; colore), out obj); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c = (TestModel.Colors)obj; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.AddToArticles(a); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art4 &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; obj = null; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.TryGetObjectByKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new System.Data.EntityKey( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string.Format(&amp;quot;{0}.{1}&amp;quot;, context.DefaultContainerName, &amp;quot;Colors&amp;quot;), &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Id&amp;quot;, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; colore), out obj); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c = (TestModel.Colors)obj; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.AddToArticles(a); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;(*) Il codice non viene mai eseguito.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2367/Fatto-Pace-Entity-Framework-Minimo-Cache.aspx"/><issued>2008-08-22T14:26:34+00:00</issued><modified>2008-08-22T14:26:34+00:00</modified><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2367/Fatto-Pace-Entity-Framework-Minimo-Cache.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2367.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2367</trackback:ping></entry><entry><title>Entity framework... un minimo di cache faceva schifo?</title><id>http://blogs.aspitalia.com/az/post2366/Entity-Framework.-Minimo-Cache-Faceva-Schifo.aspx</id><created>2008-08-21T16:50:05+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2366' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Leggero. Continuano dei test a tempo perso con l'entity framework. Siccome volevo legare delle propriet&amp;#224; ad una tabella per vedere il comportamento dell'EF (lo chiamo cos&amp;#236; amichevolmente perch&amp;#233; inizio ad avere confidenza con questa tecnologia), ho creato una struttura simile a questa:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;361&quot; alt=&quot;diagramma tabelle&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/entityframew.unminimodicachefacevaschifo_10861/image_3.png&quot; width=&quot;405&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;L'entity framework crea il tutto in modo corretto:&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;212&quot; alt=&quot;ado entity&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/entityframew.unminimodicachefacevaschifo_10861/image_6.png&quot; width=&quot;449&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;Nella tabella colors sono presenti dei record cos&amp;#236; composta:&lt;/p&gt; &lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;Id&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;Color&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;1&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;Black&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;2&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;White&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width=&quot;200&quot;&gt;3&lt;/td&gt; &lt;td  width=&quot;200&quot;&gt;Red&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Per inserire in &lt;em&gt;Articles&lt;/em&gt; nuovi record con un colore corrispondente, mi basta scrivere il codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestModel.TestEntities context = new TestModel.TestEntities()) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var c = context.Colors.Where(w =&amp;gt; w.Color == &amp;quot;White&amp;quot;).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Tutto funziona bene. Con il profiler vedo che esegue una prima query per sapere l'&lt;em&gt;id&lt;/em&gt; del colore che sar&amp;#224; poi utilizzato per l'inserimento nella tabella &lt;em&gt;Articoles&lt;/em&gt;. A chiunque sarebbe venuto lo stesso sospetto che &amp;#232; venuto a me: nel caso caso di inserimento di pi&amp;#249; oggetti &lt;em&gt;Articles&lt;/em&gt;, avendo richiedendo lo stesso colore, come si comporta l'EF?&lt;/p&gt; &lt;p&gt;Ipotizzando questo codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestModel.TestEntities context = new TestModel.TestEntities()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; string colore = &amp;quot;White&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var c = context.Colors.Where(w =&amp;gt; w.Color == colore).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; a = new TestModel.Articles(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; a.Article = &amp;quot;Art2 &amp;quot; + DateTime.Now.ToString(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; c = context.Colors.Where(w =&amp;gt; w.Color == colore).First(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; a.Colors = c; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;}&lt;/em&gt; &lt;/p&gt; &lt;p&gt;E' per due volte richiesto il colore &lt;em&gt;bianco&lt;/em&gt;. Avvio il codice, il tutto &amp;#232; inserito correttamente. Guardo con il &lt;em&gt;profiler&lt;/em&gt;... delusione: esegue per ben due volte la query per ottenere l'&lt;em&gt;id&lt;/em&gt; del colore. Una possibile soluzione? Crearsi una logica interna di cache... ok, ma un minimo di cache delle entit&amp;#224; l'avrei gradita.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2366/Entity-Framework.-Minimo-Cache-Faceva-Schifo.aspx"/><issued>2008-08-21T18:50:05+00:00</issued><modified>2008-08-21T18:50:05+00:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2366/Entity-Framework.-Minimo-Cache-Faceva-Schifo.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2366.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2366</trackback:ping></entry><entry><title>Entity Framework e il namespace EntityClient</title><id>http://blogs.aspitalia.com/az/post2363/Entity-Framework-Namespace-EntityClient.aspx</id><created>2008-08-16T14:01:17+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2363' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Sabato pomeriggio. L'entity framework permette, grazie alle classi contenuti nel namespace &lt;em&gt;EntityClient&lt;/em&gt;, la connessione e l'esecuzione di query direttamente sulle &lt;em&gt;entity&lt;/em&gt;, come se si trattasse di un database. Riferendomi sempre a grandi linee agli esempi esposti &lt;a href=&quot;http://blogs.aspitalia.com/az/post2359/lentity-framework-framework-3.5-sp.aspx&quot;&gt;qui&lt;/a&gt; e &lt;a href=&quot;http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx&quot;&gt;qui&lt;/a&gt;, ecco un banale esempio di utilizzo delle classi di questo namespace:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (System.Data.EntityClient.EntityConnection conn = new System.Data.EntityClient.EntityConnection(&quot;name=TestEntitiesCode&quot;))&lt;br /&gt; {&lt;br /&gt; conn.Open(); &lt;/em&gt; &lt;p&gt;&lt;em&gt; System.Data.EntityClient.EntityCommand comm= conn.CreateCommand();&lt;br /&gt; comm.CommandText = &quot;select na.Id, na.Names1, na.Books from TestEntitiesCode.Names as na&quot;;&lt;br /&gt; System.Data.EntityClient.EntityDataReader re = comm.ExecuteReader(System.Data.CommandBehavior.SequentialAccess);&lt;br /&gt; while (re.Read())&lt;br /&gt; {&lt;br /&gt; Response.Write(string.Format(&quot;{0}, {1} = &quot;,&lt;br /&gt; re[&quot;Id&quot;], re[&quot;Names1&quot;]));&lt;br /&gt; ShowChildren(re[&quot;Books&quot;] as System.Data.Common.DbDataReader);&lt;br /&gt; Response.Write(&quot;&amp;lt;br /&amp;gt;&quot;);&lt;br /&gt; }&lt;br /&gt; re.Close();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;private void ShowChildren(System.Data.Common.DbDataReader children)&lt;br /&gt;{&lt;br /&gt; while (children.Read())&lt;br /&gt; {&lt;br /&gt; Response.Write(&quot;[[&quot;);&lt;br /&gt; System.Data.IExtendedDataRecord columns = children as System.Data.IExtendedDataRecord;&lt;br /&gt; for (int i = 0; i &amp;lt; columns.FieldCount; i++)&lt;br /&gt; Response.Write(columns[i].ToString() + &quot;, &quot;);&lt;br /&gt; Response.Write(&quot;]]&quot;);&lt;br /&gt; }&lt;br /&gt;} &lt;/em&gt; &lt;p&gt;Due parole sulla sintassi. In &lt;em&gt;EntityConnection&lt;/em&gt; dobbiamo specificare il nome della classe del nostro model creato con VS2008 (nel dettaglio, aperto il model in VS2008 &#232; sufficiente leggere la propriet&#224; &quot;Entity Container&quot; nelle properties. Nell'esempio viene usata il &lt;em&gt;datareader&lt;/em&gt;. Per le propriet&#224; dirette come l'&lt;em&gt;id&lt;/em&gt; e il name dell'entit&#224; &lt;em&gt;Names&lt;/em&gt;, possiamo accedere direttamente con il nome stesso, ma in caso volessimo accedere, come nell'esempio, a una collection di entity come la lista dalla tabella &lt;em&gt;Books&lt;/em&gt;, dobbiamo complicare un po' le cose. L'oggetto presente in &lt;em&gt;re[&quot;Books&quot;]&lt;/em&gt; &#232; &lt;em&gt;System.Data.Query.ResultAssembly.BridgeDataReader&lt;/em&gt; ma possiamo passarlo come un DbDataReader come nell'esempio. &lt;p&gt;In ShowChildren possiamo anche andare oltre, leggendo il tipo per ogni column e agire di conseguenza. Ma non ho approfondito oltre ed &#232; sabato anche per me. Comunque, il risultato del codice &#232; il seguente: &lt;p&gt;&lt;em&gt;1, Andrea = [[1, Book 1, ]]&lt;br /&gt;2, Andrea2 = [[2, Book 2, ]][[3, Book 3, ]]&lt;br /&gt;3, Andrea3 = [[4, Book 2, ]][[5, Book 3, ]]&lt;/em&gt; &lt;p&gt;Andando a vedere con il Profiler se ci fossero ancora sorprese, troviamo la query gi&#224; spiegata &lt;a href=&quot;http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx&quot;&gt;precedentemente&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2363/Entity-Framework-Namespace-EntityClient.aspx"/><issued>2008-08-16T16:01:17+00:00</issued><modified>2008-08-16T16:01:17+00:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2363/Entity-Framework-Namespace-EntityClient.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2363.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2363</trackback:ping></entry><entry><title>Entity Framework e l'sql generato</title><id>http://blogs.aspitalia.com/az/post2361/Entity-Framework-Sql-Generato.aspx</id><created>2008-08-15T10:22:15+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2361' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Una torna a casa per qualche giorno di ferie e si becca il maltempo. Qualcuno crede alla sfortuna, altri al destino... non me ne importa niente: il problema &#232; che c'&#232; brutto tempo!&lt;/p&gt; &lt;p&gt;Allora per ammazzare un po' il tempo prima di pranzo cosa c'&#232; di meglio che giocare con leggerezza ancora con l'Entity Framework?&lt;/p&gt; &lt;p&gt;Dopo che nel &lt;a href=&quot;http://blogs.aspitalia.com/az/post2358/sql-server-2008-visual-studio-2008-sp1.aspx&quot;&gt;post precedente&lt;/a&gt; ho fatto vedere un banale inserimento, ecco come visualizzare i dati inseriti:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestEntitiesModel.TestEntitiesCode context = new TestEntitiesModel.TestEntitiesCode())&lt;br /&gt;{&lt;br /&gt; var coll = from t in context.Names.Include(&quot;Books&quot;)&lt;br /&gt; select t;&lt;br /&gt; gw1.DataSource = coll;&lt;br /&gt; gw1.DataBind();&lt;br /&gt;} &lt;/em&gt; &lt;p&gt;Sempre con la sintassi Linq, faccio una select del contenuto della Entity &lt;em&gt;Names&lt;/em&gt; e con l'include, voglio anche che sia popolata la collection dei &lt;em&gt;Books&lt;/em&gt;. Il &lt;em&gt;GridView&lt;/em&gt; nel codice html &#232; il seguente: &lt;p&gt;&lt;em&gt;&amp;lt;asp:GridView ID=&quot;gw1&quot; EnableViewState=&quot;false&quot; runat=&quot;server&quot; AutoGenerateColumns=&quot;false&quot;&amp;gt;&lt;br /&gt; &amp;lt;Columns&amp;gt;&lt;br /&gt; &amp;lt;asp:BoundField DataField=&quot;Id&quot; /&amp;gt;&lt;br /&gt; &amp;lt;asp:BoundField DataField=&quot;Names1&quot; /&amp;gt;&lt;br /&gt; &amp;lt;asp:TemplateField&amp;gt;&lt;br /&gt; &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt; &amp;lt;asp:GridView ID=&quot;gw_book&quot; runat=&quot;server&quot; DataSource='&amp;lt;%# Eval(&quot;Books&quot;) %&amp;gt;'&amp;gt;&lt;br /&gt; &amp;lt;/asp:GridView&amp;gt;&lt;br /&gt; &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt; &amp;lt;/asp:TemplateField&amp;gt;&lt;br /&gt; &amp;lt;/Columns&amp;gt;&lt;br /&gt;&amp;lt;/asp:GridView&amp;gt;&lt;/em&gt; &lt;p&gt;Il risultato &#232; il seguente: &lt;p&gt;&lt;img height=&quot;270&quot; alt=&quot;result&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_1.png&quot; width=&quot;176&quot; border=&quot;0&quot; /&gt; &lt;p&gt;Ma la mia grande curiosit&#224; &#232; che comando sql &#232; stato inviato a Sql Server. Armato di Profiler vado a curiosare e scopro una query alquanto bizzarra, almeno per me: &lt;p&gt;&lt;em&gt;SELECT &lt;br /&gt;[Project2].[Id] AS [Id], &lt;br /&gt;[Project2].[Names] AS [Names], &lt;br /&gt;[Project2].[C1] AS [C1], &lt;br /&gt;[Project2].[C2] AS [C2], &lt;br /&gt;[Project2].[Id1] AS [Id1], &lt;br /&gt;[Project2].[Title] AS [Title]&lt;br /&gt;FROM ( SELECT &lt;br /&gt; [Extent1].[Id] AS [Id], &lt;br /&gt; [Extent1].[Names] AS [Names], &lt;br /&gt; 1 AS [C1], &lt;br /&gt; [Project1].[Id] AS [Id1], &lt;br /&gt; [Project1].[Title] AS [Title], &lt;br /&gt; [Project1].[C1] AS [C2]&lt;br /&gt; FROM [dbo].[Names] AS [Extent1]&lt;br /&gt; LEFT OUTER JOIN (SELECT &lt;br /&gt; [Extent2].[NamesId] AS [NamesId], &lt;br /&gt; [Extent3].[Id] AS [Id], &lt;br /&gt; [Extent3].[Title] AS [Title], &lt;br /&gt; 1 AS [C1]&lt;br /&gt; FROM [dbo].[NamesBooks] AS [Extent2]&lt;br /&gt; INNER JOIN [dbo].[Books] AS [Extent3] ON [Extent3].[Id] = [Extent2].[BooksId] ) AS [Project1] ON [Extent1].[Id] = [Project1].[NamesId]&lt;br /&gt;) AS [Project2]&lt;br /&gt;ORDER BY [Project2].[Id] ASC, [Project2].[C2] ASC&lt;/em&gt; &lt;p&gt;Ancora una volta avevo pensato male. Avevo immaginato che facesse una prima query e quindi &lt;em&gt;n&lt;/em&gt; eventuali per la tebella figlia, e invece ha creato un unico comando con sotto query in modo molto furbo. &lt;p&gt;Il risultato della query lanciata cos&#236; come appare &#232; il seguente: &lt;p&gt;&lt;img height=&quot;152&quot; alt=&quot;query result&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_3.png&quot; width=&quot;256&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p&gt;E' lui da codice poi a fare il distict per la collection Names e con le colonne virtuali create, &lt;em&gt;C1&lt;/em&gt; e &lt;em&gt;C2&lt;/em&gt; utilizzate in caso di pi&#249; tabelle figlie.&lt;/p&gt; &lt;p&gt;Mi piace l'Entity Framework. Ne so ben poco, ma mi piace!&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2361/Entity-Framework-Sql-Generato.aspx"/><issued>2008-08-15T12:22:15+00:00</issued><modified>2008-08-15T12:22:15+00:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2361/Entity-Framework-Sql-Generato.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2361.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2361</trackback:ping></entry><entry><title>L'entity framework, e il Framework 3.5 senza SP 1</title><id>http://blogs.aspitalia.com/az/post2359/Lentity-Framework-Framework-3.5-SP.aspx</id><created>2008-08-14T12:09:36+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2359' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Come ho detto ieri ci&#242; che mi piace &#232; l'entity framework. Ma se creo un progetto web con VS2008 e SP1 che utilizza questi nuovi oggetti, e lo eseguo su un server con il Framework 3.5 senza SP1, funziona? Ne discutevo ieri con &lt;a title=&quot;link esterno&quot; href=&quot;http://blogs.dotnethell.it/david/&quot;&gt;David&lt;/a&gt;. Sinceramente pensavo di s&#236;, perch&#233; credevo che fosse tutta opera di VS2008 che, come il DataContext e Linq, crea in automatico le classi di supporto e il tutto che consente di lavorare con le entity.&lt;/p&gt; &lt;p&gt;Mi sbagliavo: faccio delle prove e il progetto non parte nemmeno perch&#233; non trova delle dll. Ecco le nuove inserite nel web.config della web application:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&amp;lt;add assembly=&quot;System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot; /&amp;gt; &lt;li&gt;&amp;lt;add assembly=&quot;System.Data.Entity.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot; /&amp;gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; Andando ancora pi&#249; in dettaglio, si pu&#242; vedere la nuova stringa di connessione in caso di utilizzo dell'entity framework:&lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;connectionStrings&amp;gt;&lt;br /&gt; &amp;lt;add name=&quot;TestEntities&quot; connectionString=&quot;metadata=res://*; provider=System.Data.SqlClient; provider connection string=&amp;amp;quot;Data Source=.\SQLSERVER2008;Initial Catalog=Test;Persist Security Info=True;User ID=yyy; Password=xxx; MultipleActiveResultSets=True&amp;amp;quot;&quot; providerName=&quot;System.Data.EntityClient&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/connectionStrings&amp;gt;&lt;/em&gt; &lt;p&gt;E il provider &lt;em&gt;EntityClient&lt;/em&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2359/Lentity-Framework-Framework-3.5-SP.aspx"/><issued>2008-08-14T14:09:36+00:00</issued><modified>2008-08-14T14:09:36+00:00</modified><slash:comments>6</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2359/Lentity-Framework-Framework-3.5-SP.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2359.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2359</trackback:ping></entry><entry><title>[OT] Un anno fa...</title><id>http://blogs.aspitalia.com/az/post2360/OT-Anno-Fa.aspx</id><created>2008-08-14T11:53:31+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2360' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;... rimanevo allibito nel vedere questa offerta di connessione a Internet a 15 Lev, circa 7 euro al mese per una 2MBit! All'epoca pagavo quasi 20 euro con la Telecom!&lt;/p&gt; &lt;p&gt;&lt;img height=&quot;640&quot; alt=&quot;sofia connessione internet&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/otunannofa_c35a/immag064_1.jpg&quot; width=&quot;480&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p&gt; Mi &#232; piaciuta Sofia, e al cirillico ci si doveva solo abituare...&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Off_Topic/&quot; rel=&quot;tag&quot;&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2360/OT-Anno-Fa.aspx"/><issued>2008-08-14T13:53:31+00:00</issued><modified>2008-08-14T13:53:31+00:00</modified><slash:comments>6</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2360/OT-Anno-Fa.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2360.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2360</trackback:ping></entry><entry><title>Sql Server 2008 e Visual Studio 2008 SP1</title><id>http://blogs.aspitalia.com/az/post2358/Sql-Server-2008-Visual-Studio-2008-SP1.aspx</id><created>2008-08-13T17:18:22+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2358' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Mentre c'&amp;#232; gente che come bistecche ai ferri si rosola al sole - mentre io sono rimasto in citt&amp;#224; e sono pi&amp;#249; bianco di Casper e non ho nemmeno vicino Christina Ricci - ecco che questi due prodotti li ho finalmente installati. Fa una certa impressione vedere l'intellisense e il debug con il Managment Studio di Sql (solo, purtroppo, per db su 2008):&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_2.png&quot;&gt;&lt;img height=&quot;233&quot; alt=&quot;image&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_thumb.png&quot; width=&quot;517&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;E trovare, finalmente, l'Entity Framework. E piacevole vedere che, con questa banalissima struttura, i vantaggi che si avranno poi con il codice:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_4.png&quot;&gt;&lt;img height=&quot;477&quot; alt=&quot;image&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_thumb_1.png&quot; width=&quot;403&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Importato tutto in VS2008 nell'oggetto &amp;quot;ADO.Net Entity Data Model&amp;quot; ho il risultato:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_6.png&quot;&gt;&lt;img height=&quot;439&quot; alt=&quot;image&quot; src=&quot;http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_thumb_2.png&quot; width=&quot;276&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Da solo VS2008 &amp;#232; stato in grado di creare le entit&amp;#224; con il corretto mapping. Vediamo che cosa posso scrivere ora:&lt;/p&gt; &lt;p&gt;&lt;em&gt;TestModel.TestEntities context = new TestModel.TestEntities(); &lt;br /&gt;TestModel.names n = new TestModel.names(); &lt;br /&gt;n.name = &amp;quot;AZ&amp;quot;; &lt;br /&gt;TestModel.books b = new TestModel.books(); &lt;br /&gt;b.title = &amp;quot;Book 1&amp;quot;; &lt;br /&gt;n.books.Add(b); &lt;br /&gt;context.AddTonames(n); &lt;br /&gt;context.SaveChanges();&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Avviato, mi sono trovato il tutto mappato correttamente nelle tabelle:&lt;/p&gt; &lt;p&gt;&lt;em&gt;SELECT *&amp;#160; FROM [names] &lt;br /&gt;SELECT *&amp;#160; FROM [books] &lt;br /&gt;SELECT *&amp;#160; FROM [names_books]&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;id&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name &lt;br /&gt;----------- -------------------------------------------------- &lt;br /&gt;5&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AZ &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;(Righe interessate: 1) &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;id&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; title &lt;br /&gt;----------- -------------------------------------------------- &lt;br /&gt;4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Book 1 &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;(Righe interessate: 1) &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;id_name&amp;#160;&amp;#160;&amp;#160;&amp;#160; id_book &lt;br /&gt;----------- ----------- &lt;br /&gt;5&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 4 &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;(Righe interessate: 1)&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Ma che ci si va a fare in ferie quando si hanno queste belle sorprese dai programmatori Microsoft? Ma chi desidera ora acque cristalline o montagne? Perch&amp;#233; dovrei desiderare di poter andare con la mia bici? Perch&amp;#233; dovrei stare ad alta quota che c'&amp;#232; pure fresco quando invece posso divertirmi con l'entity framework? Il debug di Sql 2008 mi far&amp;#224; compagnia in questi giorni, alla faccia vostra!&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2358/Sql-Server-2008-Visual-Studio-2008-SP1.aspx"/><issued>2008-08-13T19:18:22+00:00</issued><modified>2008-08-13T19:18:22+00:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2358/Sql-Server-2008-Visual-Studio-2008-SP1.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2358.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2358</trackback:ping></entry><entry><title>[OT] Dove non sono andato in vacanza quest'anno</title><id>http://blogs.aspitalia.com/az/post2357/OT-Andato-Vacanza-Questanno.aspx</id><created>2008-08-11T17:33:00+00:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2357' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;Se ne parlava come al solito con gli amici dall'anno scorso. Si doveva decidere solo tra due paesi: l'&lt;a title=&quot;Link esterno&quot; href=&quot;http://www.viaggiaresicuri.it/index.php?id=322&amp;amp;tx_ttnews[tt_news]=3125&amp;amp;tx_ttnews[backPid]=3054&amp;amp;no_cahce=1&amp;amp;mese=&amp;amp;lim=10&amp;amp;country=431&quot;&gt;Armenia&lt;/a&gt; o la &lt;a href=&quot;http://www.viaggiaresicuri.it/index.php?id=322&amp;amp;tx_ttnews[tt_news]=3254&amp;amp;tx_ttnews[backPid]=3054&amp;amp;no_cahce=1&amp;amp;mese=&amp;amp;lim=10&amp;amp;country=435&quot; title=&quot;Link esterno&quot;&gt;Georgia&lt;/a&gt;. Fino a febbraio di quest'anno ne parlavamo, ma poi problemi &lt;a title=&quot;Mio blog precedente&quot; href=&quot;http://blogs.aspitalia.com/az/post2307/OT-Problema-Serio-Dischi.aspx&quot;&gt;miei&lt;/a&gt; e di altre persone del gruppo ci hanno fatto desistere da questo viaggio.&lt;br /&gt;&lt;br /&gt;Come si dice, non tutto il male viene per nuocere sapendo che saremmo stati in uno di quegli Stati proprio questa settimana.&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Off_Topic/&quot; rel=&quot;tag&quot;&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/az/post2357/OT-Andato-Vacanza-Questanno.aspx"/><issued>2008-08-11T19:33:00+00:00</issued><modified>2008-08-11T19:33:00+00:00</modified><slash:comments>5</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2357/OT-Andato-Vacanza-Questanno.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2357.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2357</trackback:ping></entry></feed>