<?xml version="1.0" encoding="iso-8859-15"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>AZ - Il blog di Andrea Zani</title><link>http://blogs.aspitalia.com/az/</link><description>AZ - Il blog di Andrea Zani</description><language>it-it</language><managingEditor>noreply(at)aspitalia.com(AZ - Il blog di Andrea Zani)</managingEditor><webMaster>daniele(at)aspitalia.com(Daniele Bochicchio)</webMaster><copyright>1998-2008 ASPItalia.com/AZ - Il blog di Andrea Zani</copyright><generator>Generated by feed.ASPItalia.com 'Weyoh' 4.8.902</generator><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><sy:updateBase>1998-01-01T12:00+00:00</sy:updateBase><image><title>AZ - Il blog di Andrea Zani</title><url>http://gui.aspitalia.com/images/aspitalia_syndication.gif</url><link>http://blogs.aspitalia.com/az/</link></image><item><title>Intellisense in Sql Server 2008</title><link>http://blogs.aspitalia.com/az/post2382/Intellisense-Sql-Server-2008.aspx</link><pubDate>Thu, 04 Sep 2008 17:48:52 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2382' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;C'&amp;#232; una tabella:&lt;/p&gt; &lt;p&gt;&lt;img height="226" alt="lista tabelle in sql server 2008" src="http://blogs.aspitalia.com/img/andrewz/intellisenseinsqlserver2008_115fa/image_6.png" width="226" border="0" /&gt; &lt;/p&gt; &lt;p&gt;L'intellisense c'&amp;#232;?&lt;/p&gt; &lt;p&gt;&lt;img height="260" alt="intellisense in sql server 2008" src="http://blogs.aspitalia.com/img/andrewz/intellisenseinsqlserver2008_115fa/image_5.png" width="514" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Che bello. Cancello la tabella. Rifaccio una query e cosa mi compare?&lt;/p&gt; &lt;p&gt;&lt;img height="305" alt="intellisense con la tabella cancellata" src="http://blogs.aspitalia.com/img/andrewz/intellisenseinsqlserver2008_115fa/image_9.png" width="524" border="0" /&gt;&lt;/p&gt; &lt;p&gt;Ma se l'ho cancellata!!!&lt;/p&gt; &lt;p&gt;Il bello avviene anche con tabelle nuove che non vengono viste dall'intellisense del Managment Studio di Sql Server 2008. Lo si deve riavviare per aggiornare il tutto. &lt;/p&gt; &lt;p&gt;O mi &amp;#232; sfuggito qualcosa? La delusione per&amp;#242; c'&amp;#232;. Bel &lt;strong&gt;&lt;em&gt;bug&lt;/em&gt;&lt;/strong&gt;!!!&lt;/p&gt; &lt;p&gt;&lt;em&gt;Questo problema me l'ha fatto notare un collega, da quando c'&amp;#232; EF, Sql server non lo guardo pi&amp;#249; :-)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Database/" rel="tag"&gt;Database&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/SQL_Server/" rel="tag"&gt;SQL Server&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, Database, SQL Server</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2382/Intellisense-Sql-Server-2008.aspx</guid><slash:comments>10</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2382/Intellisense-Sql-Server-2008.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2382.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2382</trackback:ping></item><item><title>Entity Framework e pi&amp;#249; tabelle in una entity</title><link>http://blogs.aspitalia.com/az/post2379/Entity-Framework-Tabelle-Entity.aspx</link><pubDate>Wed, 03 Sep 2008 07:09:34 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2379' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Breve e coinciso. Due tabelle in una sola &lt;em&gt;entity&lt;/em&gt;. L'&lt;em&gt;Entity Framework&lt;/em&gt; lo permette con pochi passaggi e &lt;strong&gt;non&lt;/strong&gt; in automatico.&lt;/p&gt; &lt;p&gt;Mi servono due tabelle. Eccole:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tutorials&lt;/strong&gt;&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;strong&gt;Nome campo&lt;/strong&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;strong&gt;Tipo e altro&lt;/strong&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Id&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;Int, key, Auto increment&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Name&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;nvarchar&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Description&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;Text&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;strong&gt;Tutorials2&lt;/strong&gt;&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;strong&gt;Nome campo&lt;/strong&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;strong&gt;Tipo e altro&lt;/strong&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Id&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;Int, key&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Name&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;nvarchar&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;Description&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&gt;&lt;em&gt;Text&lt;/em&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Ora importiamo le due tabelle nel &lt;em&gt;designer&lt;/em&gt; di Visual Studio 2008. Creer&amp;#224; due &lt;em&gt;entity&lt;/em&gt; distinte. Non ci servono a nulla. Vanno cancellate. Quindi dalla &lt;em&gt;toolbar&lt;/em&gt;, inserire una nuovo oggetto &lt;em&gt;Entity&lt;/em&gt; e si mappano all'interno le due tabelle e tutti i campi, naturalmente inserendo nell'editor tante propriet&amp;#224; quante ne servono. Il risultato finale deve essere simile a questo:&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;img height="568" alt="mapping entity framework" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkepitabelleinunaentity_80c1/immagine%204_3.gif" width="510" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Tutto fatto. Ora possiamo farne quello che vogliamo:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (pubsModel.pubsEntities context = new pubsModel.pubsEntities()) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; pubsModel.Tutorials obj = new pubsModel.Tutorials(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; obj.Name1 = &amp;quot;A1&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; obj.Name2 = &amp;quot;A2&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; obj.Description1 = &amp;quot;D1&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; obj.Description2 = &amp;quot;D2&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.AddToTutorialsSet(obj); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; context.SaveChanges(); &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Un ringraziamento a &lt;a title="link esterno" href="http://blogs.dotnethell.it/david/"&gt;David&lt;/a&gt; che mi ha dato un ottimo suggerimento a riguardo. Ora ho solo un unico dubbio e poi con l'&lt;em&gt;EF&lt;/em&gt; spacco tutto: dividere una tabella in due o pi&amp;#249; &lt;em&gt;entity&lt;/em&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2379/Entity-Framework-Tabelle-Entity.aspx</guid><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2379/Entity-Framework-Tabelle-Entity.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2379.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2379</trackback:ping></item><item><title>L'Entity Framework e le custom class coinvolte nei where...</title><link>http://blogs.aspitalia.com/az/post2378/LEntity-Framework-Custom-Class-Coinvolte-Where.aspx</link><pubDate>Sun, 31 Aug 2008 01:04:02 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2378' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Riprendo il solito esempio di &lt;em&gt;entity&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;img alt="entity in visual studio 2008" src="http://blogs.aspitalia.com/img/andrewz/entityframew.unminimodicachefacevaschifo_10861/image_6.png" /&gt; &lt;/p&gt; &lt;p&gt;Ipotizzando di voler recuperare tutti gli &lt;em&gt;Articles&lt;/em&gt; con un determinato colore si potrebbe essere spinti a scrivere:&lt;/p&gt; &lt;p&gt;&lt;em&gt;var c=Context.Colors.Where(cc=&amp;gt;cc.Id==1).First();&lt;br /&gt;var coll=from ar in Context.Articles.Include("Colors")&lt;br /&gt; where ar.Colors=c&lt;br /&gt; select ar;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Semplicemente, avendo una &lt;em&gt;entity&lt;/em&gt; voglio vedere tutte le &lt;em&gt;entity&lt;/em&gt; che hanno come &lt;em&gt;property&lt;/em&gt; questo oggetto. Eseguita, però, si ottienere questo errore:&lt;/p&gt; &lt;p&gt;&lt;em&gt;Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Questo perché l'EF non permette il confronto tra &lt;em&gt;oggetti complessi&lt;/em&gt;. La soluzione è banale, anzi, in qualche caso più semplice (nel caso di &lt;em&gt;web control&lt;/em&gt; che ritornano un valore numerico per identificare una scelta di un utente, per sempio da un &lt;em&gt;dropdownlist&lt;/em&gt;):&lt;/p&gt; &lt;p&gt;&lt;em&gt;int c=int.Parse(ddl_colors.SelectedValue); // &amp;lt;- prendo il colore selezionato&lt;br /&gt;var coll=from ar in Context.Articles.Include("Colors")&lt;br /&gt; where ar.Colors.Id=c&lt;br /&gt; select ar;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Oppure:&lt;/p&gt; &lt;p&gt;&lt;em&gt;var c=Context.Colors.Where(cc=&amp;gt;cc.Id==1).First();&lt;br /&gt;var coll=from ar in Context.Articles.Include("Colors")&lt;br /&gt; where ar.Colors.Id=c.Id&lt;br /&gt; select ar;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Soluzione semplice, ma è sempre bene saperla.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2378/LEntity-Framework-Custom-Class-Coinvolte-Where.aspx</guid><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2378/LEntity-Framework-Custom-Class-Coinvolte-Where.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2378.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2378</trackback:ping></item><item><title>Entity Framework e l'ereditariet&amp;#224; (Single Table Inheritance)</title><link>http://blogs.aspitalia.com/az/post2377/Entity-Framework-Ereditarieta-Single-Table-Inheritance.aspx</link><pubDate>Sat, 30 Aug 2008 13:07:56 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2377' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Visto che in questi gioni sto usando parecchio con l'&lt;em&gt;Entity Framework&lt;/em&gt; questa &lt;em&gt;Table Per Hierarchy&lt;/em&gt; (Emanuele mi correggerà se, come al solito, sbaglio la nomenclatura), ecco due appunti su come si realizza con l'editor che mette a disposizione Visual Studio 2008.&lt;/p&gt; &lt;p&gt;L'inizio è questa semplice tabella dal nome &lt;em&gt;BaseContents&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;img height="180" alt="struttura tabella" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelereditarietsingletablei_c776/image_1.png" width="340" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Da questa singola tabella è possibile estrarre due &lt;em&gt;entity&lt;/em&gt; distinte. Nel mio caso:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;TextContents &lt;li&gt;LinkContents&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;La prima utilizzata per memorizzare il contenuto reale di un eventuale testo, la seconda per link a risorse esterne. All'interno di questa singola tabella sono contenuti tutti i campi per memorizzare queste informazioni. L'unico campo aggiuntivo, che farà da &lt;em&gt;discriminante&lt;/em&gt;, come si vedrà di seguito, è &lt;em&gt;Type&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Creato in Visual Studio 2008 un nuovo oggetto &lt;em&gt;ADO.Net Entity Data Model&lt;/em&gt;, e importanto all'interno di questo oggetto la tabella sopra mostrata, si avrà la prima &lt;em&gt;entity&lt;/em&gt; creata in automatico dall'ambiente di sviluppo con tutti i campi interessati.&lt;/p&gt; &lt;p&gt;Ora è possibile aggiunere le entity mancanti, &lt;em&gt;TextContents&lt;/em&gt; e &lt;em&gt;LinkContents&lt;/em&gt;, ereditandole direttamente da questa (è sufficiente cliccare con il tasto destro all'interno dell'editor e selezionare &lt;em&gt;Add&lt;/em&gt; -&amp;gt; &lt;em&gt;Entity&lt;/em&gt;). Aggiunte le due entity ecco cosa abbiamo in VS 2008:&lt;/p&gt; &lt;p&gt;&lt;img height="346" alt="entity" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelereditarietsingletablei_c776/image_7.png" width="342" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Ora possiamo spostare le &lt;em&gt;property&lt;/em&gt; di nostro interesse nelle sottostanti &lt;em&gt;entity &lt;/em&gt;per ottenere questo:&lt;/p&gt; &lt;p&gt;&lt;img height="376" alt="entity" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelereditarietsingletablei_c776/image_9.png" width="340" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Dalla window Mapping details, mappiamo la tabella e assicurati che tutti i campi interessati siamo mappati correttamente, possiamo inserire la condizione discriminante, in modo che nell'uso di una o dell'altra entity, siano salvati i dati corretti nella tabella. Nulla di difficile, sempre da &lt;em&gt;Mapping details&lt;/em&gt;, si aggiunge nelle &lt;em&gt;condition&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.aspitalia.com/img/andrewz/entityframeworkelereditarietsingletablei_c776/image_10.png" atomicselection="true"&gt;&lt;img height="174" alt="conditions" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelereditarietsingletablei_c776/image_thumb_5.png" width="520" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In questo caso ho inserito il valore &lt;em&gt;1&lt;/em&gt; in &lt;em&gt;Type&lt;/em&gt; per il &lt;em&gt;TextContents&lt;/em&gt;, e &lt;em&gt;2&lt;/em&gt; per il &lt;em&gt;LinkContents&lt;/em&gt;. Sembra tutto fatto, ma ecco l'amara sorpresa che ho trovato compilando il tutto:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Error 1 Error 3032: Problem in Mapping Fragment starting at line 49: Condition member 'BaseContents.Type' with a condition other than 'IsNull=False' is mapped. Either remove the condition on BaseContents.Type or remove it from the mapping.&lt;/strong&gt; &lt;p&gt;Scopro che &lt;em&gt;Type&lt;/em&gt; crea un problema. Il mio primo tentativo di cancellazione di questa property dall'&lt;em&gt;entity&lt;/em&gt; &lt;em&gt;BaseContents&lt;/em&gt; mi porta un nuovo errore: &lt;p&gt;&lt;strong&gt;Error 1 Error 3023: Problem in Mapping Fragments starting at lines 48, 54, 59: Column BaseContents.Type has no default value and is not nullable. A column value is required to store entity data.&lt;br /&gt;An Entity with Key (PK) will not round-trip when:&lt;br /&gt; (PK is in 'BaseContents' EntitySet AND Entity is type TestEntitiesModel.BaseContents)&lt;/strong&gt; &lt;p&gt;Alla fine scopro la soluzione da un &lt;a href="http://weblogs.asp.net/zeeshanhirani/archive/2008/08/16/single-table-inheritance-in-entity-framework.aspx"&gt;blog&lt;/a&gt; di &lt;a href="http://weblogs.asp.net/zeeshanhirani/default.aspx"&gt;Zeeshan Hirani&lt;/a&gt; (che spiega il tutto in modo molto più dettagliato, ma visto che ho scritto fino a qua, non ho voglia di buttare il tutto) che ringrazio perché mi ha fatto trovare immediatamente la soluzione. E' sufficiente modificare la &lt;em&gt;property&lt;/em&gt; &lt;em&gt;Abstract&lt;/em&gt; dell&lt;em&gt;'Entity BaseContents&lt;/em&gt; in &lt;em&gt;true&lt;/em&gt;, per eliminare ogni errore. &lt;p&gt;Ora da codice possiamo inserire e leggere da questa tabella con due &lt;em&gt;entity&lt;/em&gt; separate: &lt;p&gt;&lt;em&gt;using (TestEntitiesModel.TestEntitiesEntities context = new TestEntitiesModel.TestEntitiesEntities())&lt;br /&gt;{&lt;br /&gt; TestEntitiesModel.TextContents c = new TestEntitiesModel.TextContents();&lt;br /&gt; c.Name = "Example 1";&lt;br /&gt; c.Content = "Content text bla bla bla";&lt;br /&gt; context.AddToBaseContents(c);&lt;br /&gt; TestEntitiesModel.LinkContents l = new TestEntitiesModel.LinkContents();&lt;br /&gt; l.Name = "Example 2";&lt;br /&gt; l.Link = "www.aspitalia.com";&lt;br /&gt; l.Impressions = 0;&lt;br /&gt; context.AddToBaseContents(l);&lt;br /&gt; context.SaveChanges();&lt;br /&gt;} &lt;/em&gt; &lt;p&gt;Visualizzando il contenuto della tabella troveremo:&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="510" border="1" unselectable="on"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width="66"&gt;I&lt;strong&gt;d&lt;/strong&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;strong&gt;Link&lt;/strong&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;strong&gt;Impressions&lt;/strong&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="66"&gt;1&lt;/td&gt; &lt;td  width="66"&gt;Example1&lt;/td&gt; &lt;td  width="66"&gt;&lt;em&gt;null&lt;/em&gt;&lt;/td&gt; &lt;td  width="66"&gt;&lt;em&gt;null&lt;/em&gt;&lt;/td&gt; &lt;td  width="66"&gt;Content text bla bla bla&lt;/td&gt; &lt;td  width="66"&gt;1&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="66"&gt;2&lt;/td&gt; &lt;td  width="66"&gt;Example2&lt;/td&gt; &lt;td  width="66"&gt;www.aspitalia.com&lt;/td&gt; &lt;td  width="66"&gt;1&lt;/td&gt; &lt;td  width="66"&gt;&lt;em&gt;null&lt;/em&gt;&lt;/td&gt; &lt;td  width="66"&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Per leggere:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using (TestEntitiesModel.TestEntitiesEntities context = new TestEntitiesModel.TestEntitiesEntities())&lt;br /&gt;{&lt;br /&gt; var coll = from c in context.BaseContents.OfType&amp;lt;TestEntitiesModel.TextContents&amp;gt;()&lt;br /&gt; orderby c.Content ascending&lt;br /&gt; select c;&lt;br /&gt; foreach (var item in coll)&lt;br /&gt; {&lt;br /&gt; Response.Write(string.Format("{0} {1} {2}&amp;lt;br /&amp;gt;",&lt;br /&gt; item.Id,item.Name,item.Content));&lt;br /&gt; }&lt;br /&gt;} &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Questa volta per specificare l'&lt;em&gt;entity&lt;/em&gt; da leggere, dobbiamo utilizzare l'&lt;em&gt;OfType&lt;/em&gt; come da esempio. Se volessimo richiedere l'&lt;em&gt;entity&lt;/em&gt; &lt;em&gt;LinkContents&lt;/em&gt;, avremmo duvuto scrivere:&lt;/p&gt;&lt;em&gt; var coll = from c in context.BaseContents.OfType&amp;lt;TestEntitiesModel.&lt;strong&gt;Link&lt;/strong&gt;Contents&amp;gt;()&lt;/em&gt;&lt;br /&gt; &lt;p&gt;Oltre al &lt;em&gt;Table Per Hierarchy (Single Table Inheritance)&lt;/em&gt; l'&lt;em&gt;EntityFramework&lt;/em&gt; mette a disposizione altri due tipi di &lt;em&gt;inheritance&lt;/em&gt;:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;em&gt;Table Per Type&lt;/em&gt; &lt;li&gt;&lt;em&gt;Table Per Concrete Class&lt;/em&gt; &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Ma le cosa iniziano a complicarsi un po' con l'editor di VS2008.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Visual_Studio/" rel="tag"&gt;Visual Studio&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET, Visual Studio</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2377/Entity-Framework-Ereditarieta-Single-Table-Inheritance.aspx</guid><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/az/post2377/Entity-Framework-Ereditarieta-Single-Table-Inheritance.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2377.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2377</trackback:ping></item><item><title>L'entity Framework e i vincoli FOREIGN KEY</title><link>http://blogs.aspitalia.com/az/post2374/Lentity-Framework-Vincoli-FOREIGN-KEY.aspx</link><pubDate>Thu, 28 Aug 2008 07:12:13 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2374' border="0" style="width:1px; height:1px;" /&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="http://tags.aspitalia.com/Database/" rel="tag"&gt;Database&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET, Database</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2374/Lentity-Framework-Vincoli-FOREIGN-KEY.aspx</guid><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></item><item><title>Data Service Viewer</title><link>http://blogs.aspitalia.com/az/post2373/Data-Service-Viewer.aspx</link><pubDate>Thu, 28 Aug 2008 07:09:20 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2373' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Interessante questo &lt;a title="link esterno" href="http://weblogs.asp.net/vardi/archive/2008/08/27/ado-net-data-services-viewer-tool.aspx"&gt;tool&lt;/a&gt;. Anche se &lt;a title="link esterno" href="http://astoria.mslivelabs.com/"&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="http://localhost:1035/websiteentity2/webdataservice.svc"&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="459" alt="data service viewer" src="http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%202_3.gif" width="524" border="0" /&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="http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%201_2.gif"&gt;&lt;img height="388" alt="data service viewer" src="http://blogs.aspitalia.com/img/andrewz/dataserviceviewer_80c0/immagine%201_thumb.gif" width="523" border="0" /&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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2373/Data-Service-Viewer.aspx</guid><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></item><item><title>Lazy Loading con l'Entity Framework</title><link>http://blogs.aspitalia.com/az/post2372/Lazy-Loading-Entity-Framework.aspx</link><pubDate>Wed, 27 Aug 2008 11:33:57 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2372' border="0" style="width:1px; height:1px;" /&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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2372/Lazy-Loading-Entity-Framework.aspx</guid><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></item><item><title>4 desktop virtuali su Windows</title><link>http://blogs.aspitalia.com/az/post2371/Desktop-Virtuali-Windows.aspx</link><pubDate>Tue, 26 Aug 2008 12:01:02 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2371' border="0" style="width:1px; height:1px;" /&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="link esterno" href="http://blogs.dotnethell.it/windowsvista/post_14028.aspx"&gt;Leggo&lt;/a&gt; ora che &amp;#232; presente questo &lt;a title="link esterno" href="http://technet.microsoft.com/en-us/sysinternals/cc817881.aspx"&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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2371/Desktop-Virtuali-Windows.aspx</guid><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></item><item><title>A volte ritornano... GridView vs Repeater vs ListView vs Custom</title><link>http://blogs.aspitalia.com/az/post2370/Volte-Ritornano.-GridView-Repeater-ListView-Custom.aspx</link><pubDate>Tue, 26 Aug 2008 07:20:37 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2370' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;&lt;a href="http://blogs.aspitalia.com/az/post549/ancora-prestazioni-datagrid-datalist-repeater-.aspx"&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="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width="200"&gt;&lt;em&gt;&lt;strong&gt;GridView&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="200"&gt;&lt;em&gt;&lt;strong&gt;Repeater&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="200"&gt;&lt;em&gt;&lt;strong&gt;Repeater ottimizzato&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="200"&gt;&lt;em&gt;&lt;strong&gt;ListView&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="200"&gt;&lt;em&gt;&lt;strong&gt;ListView ottimizzato&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="200"&gt;&lt;em&gt;&lt;strong&gt;Custom code&lt;/strong&gt;&lt;/em&gt;&lt;/td&gt; &lt;td  width="200"&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="http://tags.aspitalia.com/ASP.NET/" rel="tag"&gt;ASP.NET&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/ASP.NET_2.0/" rel="tag"&gt;ASP.NET 2.0&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/ASP.NET_3.5/" rel="tag"&gt;ASP.NET 3.5&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Databinding/" rel="tag"&gt;Databinding&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Datagrid/" rel="tag"&gt;Datagrid&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/GridView/" rel="tag"&gt;GridView&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET, ASP.NET, ASP.NET 2.0, ASP.NET 3.5, Databinding, Datagrid, GridView</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2370/Volte-Ritornano.-GridView-Repeater-ListView-Custom.aspx</guid><slash:comments>18</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></item><item><title>L'Entity Framework e l'ObjectDataSource</title><link>http://blogs.aspitalia.com/az/post2369/LEntity-Framework-ObjectDataSource.aspx</link><pubDate>Sun, 24 Aug 2008 19:26:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2369' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Anche se con l'SP1 del Framework 3.5 è 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="http://blogs.aspitalia.com/daniele"&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ò. Quando si cerca di fare qualcosa di più 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à (nel mio caso con l'ausilio dell'&lt;em&gt;Entity Framework&lt;/em&gt;) non ci sono problemi: persino altre entità memorizzate in proprietà vengono visualizzate correttamente. Come nell'esempio già &lt;a href="http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx"&gt;visto&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img alt="gridview" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_1.png" /&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è con proprietà 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ì, ma l'entità qui trattata ha anche come proprietà 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="entity framework" src="http://blogs.aspitalia.com/img/andrewz/sqlserver2008evisualstudio2008sp1_10f47/image_6.png" /&gt; &lt;/p&gt;&lt;p&gt;Per visualizzare il tutto in modalità &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 è un po' forzato, ma un caso reale potrebbe essere la creazione di un nuovo utente e il collegamento ad esso di una o più role per autorizzazione varie (visualizzate in modalità &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ù 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à 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é 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("Books", 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ù semplice). Ora il codice per l'inserimento dovrebbe accettare anche questi dati aggiuntivi, ma ecco il secondo problema della giornata: quelle entità 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ù immediate e semplici. Vero? Ditemi di sì! :(&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2369/LEntity-Framework-ObjectDataSource.aspx</guid><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></item><item><title>SP vs Linq vs Entity Framework in scrittura</title><link>http://blogs.aspitalia.com/az/post2368/SP-Linq-Entity-Framework-Scrittura.aspx</link><pubDate>Fri, 22 Aug 2008 21:11:44 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2368' border="0" style="width:1px; height:1px;" /&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ù 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="320" alt="struttura tabelle" src="http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_1.png" width="358" border="0" /&gt;&lt;/p&gt; &lt;p&gt;Il mio test è 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="298" alt="datacontext di linq" src="http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_3.png" width="236" border="0" /&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="352" alt="l'entity framework creato da vs2008" src="http://blogs.aspitalia.com/img/andrewz/spvslinqvsentityframeworkinscrittura_141e2/image_5.png" width="182" border="0" /&gt;&lt;/p&gt; &lt;p&gt; Avvio più volte i test per ogni tecnologia utilizzata. La media è la seguente:&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="400" border="1" unselectable="on"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width="133"&gt;&lt;strong&gt;Stored procedure&lt;/strong&gt;&lt;/td&gt; &lt;td  width="133"&gt;&lt;strong&gt;Linq to Sql&lt;/strong&gt;&lt;/td&gt; &lt;td  width="133"&gt;&lt;strong&gt;Entity Framework&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="133"&gt;6.75&lt;em&gt;s&lt;/em&gt;&lt;/td&gt; &lt;td  width="133"&gt;20.60&lt;em&gt;s&lt;/em&gt;&lt;/td&gt; &lt;td  width="133"&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à detto, non ne avevo il minimo dubbio: il tutto è ottimizzato al meglio, ed ho cercato anche da codice di ottimizzare il più possibile la creazione di oggetti e il passaggio di parametri. La delusione è stata invece per Linq, che le prende sonoramente anche dall'&lt;em&gt;Entity Framework&lt;/em&gt; che si dimostra molto più 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 è 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ù 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 è 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ò 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="http://tags.aspitalia.com/ADO.NET_Entity_Framework/" rel="tag"&gt;ADO.NET Entity Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/.NET_Framework_3.5/" rel="tag"&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/LINQ/" rel="tag"&gt;LINQ&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Database/" rel="tag"&gt;Database&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET, ADO.NET Entity Framework, .NET Framework 3.5, LINQ, Database</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2368/SP-Linq-Entity-Framework-Scrittura.aspx</guid><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></item><item><title>Ho fatto pace con l'Entity Framework: un minimo di cache!</title><link>http://blogs.aspitalia.com/az/post2367/Fatto-Pace-Entity-Framework-Minimo-Cache.aspx</link><pubDate>Fri, 22 Aug 2008 12:26:34 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2367' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Nel &lt;a href="http://blogs.aspitalia.com/az/post2366/entity-framework.-minimo-cache-faceva-schifo.aspx"&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="http://blogs.aspitalia.com/daniele/"&gt;Daniele&lt;/a&gt; e &lt;a href="http://blogs.aspitalia.com/ricciolo/"&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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2367/Fatto-Pace-Entity-Framework-Minimo-Cache.aspx</guid><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></item><item><title>Entity framework... un minimo di cache faceva schifo?</title><link>http://blogs.aspitalia.com/az/post2366/Entity-Framework.-Minimo-Cache-Faceva-Schifo.aspx</link><pubDate>Thu, 21 Aug 2008 16:50:05 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2366' border="0" style="width:1px; height:1px;" /&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="361" alt="diagramma tabelle" src="http://blogs.aspitalia.com/img/andrewz/entityframew.unminimodicachefacevaschifo_10861/image_3.png" width="405" border="0" /&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="212" alt="ado entity" src="http://blogs.aspitalia.com/img/andrewz/entityframew.unminimodicachefacevaschifo_10861/image_6.png" width="449" border="0" /&gt; &lt;/p&gt; &lt;p&gt;Nella tabella colors sono presenti dei record cos&amp;#236; composta:&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="400" border="0"&gt;&lt;tbody&gt; &lt;tr&gt; &lt;td  width="200"&gt;Id&lt;/td&gt; &lt;td  width="200"&gt;Color&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;1&lt;/td&gt; &lt;td  width="200"&gt;Black&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;2&lt;/td&gt; &lt;td  width="200"&gt;White&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  width="200"&gt;3&lt;/td&gt; &lt;td  width="200"&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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2366/Entity-Framework.-Minimo-Cache-Faceva-Schifo.aspx</guid><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></item><item><title>Entity Framework e il namespace EntityClient</title><link>http://blogs.aspitalia.com/az/post2363/Entity-Framework-Namespace-EntityClient.aspx</link><pubDate>Sat, 16 Aug 2008 14:01:17 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2363' border="0" style="width:1px; height:1px;" /&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="http://blogs.aspitalia.com/az/post2359/lentity-framework-framework-3.5-sp.aspx"&gt;qui&lt;/a&gt; e &lt;a href="http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx"&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("name=TestEntitiesCode"))&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 = "select na.Id, na.Names1, na.Books from TestEntitiesCode.Names as na";&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("{0}, {1} = ",&lt;br /&gt; re["Id"], re["Names1"]));&lt;br /&gt; ShowChildren(re["Books"] as System.Data.Common.DbDataReader);&lt;br /&gt; Response.Write("&amp;lt;br /&amp;gt;");&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("[[");&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() + ", ");&lt;br /&gt; Response.Write("]]");&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 è sufficiente leggere la proprietà "Entity Container" nelle properties. Nell'esempio viene usata il &lt;em&gt;datareader&lt;/em&gt;. Per le proprietà dirette come l'&lt;em&gt;id&lt;/em&gt; e il name dell'entità &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["Books"]&lt;/em&gt; è &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 è sabato anche per me. Comunque, il risultato del codice è 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à spiegata &lt;a href="http://blogs.aspitalia.com/az/post2361/entity-framework-sql-generato.aspx"&gt;precedentemente&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2363/Entity-Framework-Namespace-EntityClient.aspx</guid><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></item><item><title>Entity Framework e l'sql generato</title><link>http://blogs.aspitalia.com/az/post2361/Entity-Framework-Sql-Generato.aspx</link><pubDate>Fri, 15 Aug 2008 10:22:15 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2361' border="0" style="width:1px; height:1px;" /&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 è che c'è brutto tempo!&lt;/p&gt; &lt;p&gt;Allora per ammazzare un po' il tempo prima di pranzo cosa c'è di meglio che giocare con leggerezza ancora con l'Entity Framework?&lt;/p&gt; &lt;p&gt;Dopo che nel &lt;a href="http://blogs.aspitalia.com/az/post2358/sql-server-2008-visual-studio-2008-sp1.aspx"&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("Books")&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 è il seguente: &lt;p&gt;&lt;em&gt;&amp;lt;asp:GridView ID="gw1" EnableViewState="false" runat="server" AutoGenerateColumns="false"&amp;gt;&lt;br /&gt; &amp;lt;Columns&amp;gt;&lt;br /&gt; &amp;lt;asp:BoundField DataField="Id" /&amp;gt;&lt;br /&gt; &amp;lt;asp:BoundField DataField="Names1" /&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="gw_book" runat="server" DataSource='&amp;lt;%# Eval("Books") %&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 è il seguente: &lt;p&gt;&lt;img height="270" alt="result" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_1.png" width="176" border="0" /&gt; &lt;p&gt;Ma la mia grande curiosità è che comando sql è 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ì come appare è il seguente: &lt;p&gt;&lt;img height="152" alt="query result" src="http://blogs.aspitalia.com/img/andrewz/entityframeworkelsqlgenerato_adf2/image_3.png" width="256" border="0" /&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ù 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="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2361/Entity-Framework-Sql-Generato.aspx</guid><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></item></channel></rss>