Entity Framework 6 http://blogs.ugidotnet.org/PietroLibroBlog/category/Entity Framework 6.aspx Entity Framework 6 it-IT Pietro Libro pietro.libro@libero.it Subtext Version 2.6.0.0 EF 6.1 : What&rsquo;s new (3) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx <p>Supporto a “.ToString()” e “String.Concat()”, un esempio:</p> <pre class="csharpcode">var queryConcat = from c <span class="kwrd">in</span> db.Vehicles <span class="kwrd">where</span> <span class="kwrd">string</span>.Concat(c.EngineSize, c.HP).Equals(<span class="str">"1600110"</span>) select c; var queryToString = from c <span class="kwrd">in</span> db.Vehicles <span class="kwrd">where</span> c.HP.ToString().Equals(<span class="str">"110"</span>) select c;</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Abbiamo due Query LINQ che filtrano i dati in base a condizioni su stringhe, la prima “tira fuori” tutti i veicoli dove la concatenazione dei valori delle proprietà “EngineSize” e “HP” è uguale a “1600110”, mentre la seconda esegue un filtro su di un valore intero convertio in stringa. Se proviamo ad eseguire il codice in un ambiente con EF 6.0 otteniamo un’eccezione a runtime in tutti e due i casi:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_thumb.png" width="244" height="223" /></a></p> <p>Con EF 6.1 le query sono eseguite correttamente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-3_7B13/image_thumb_1.png" width="244" height="165" /></a></p> <p>Cosa succede dietro le quinte:</p> <pre class="csharpcode"><span class="kwrd">SELECT</span> [GroupBy1].[A1] <span class="kwrd">AS</span> [C1] <span class="kwrd">FROM</span> ( <span class="kwrd">SELECT</span> <span class="kwrd">COUNT</span>(1) <span class="kwrd">AS</span> [A1] <span class="kwrd">FROM</span> [DomusDotNet].[Vehicles] <span class="kwrd">AS</span> [Extent1] <span class="kwrd">WHERE</span> N<span class="str">'1600110'</span> = (<span class="kwrd">CASE</span> <span class="kwrd">WHEN</span> ([Extent1].[EngineSize] <span class="kwrd">IS</span> <span class="kwrd">NULL</span>) <span class="kwrd">THEN</span> N<span class="str">''</span> <span class="kwrd">ELSE</span> [Extent1].[EngineSize] <span class="kwrd">END</span> + <span class="kwrd">CAST</span>( [Extent1].[HP] <span class="kwrd">AS</span> nvarchar(<span class="kwrd">max</span>))) ) <span class="kwrd">AS</span> [GroupBy1] <span class="kwrd">SELECT</span> [GroupBy1].[A1] <span class="kwrd">AS</span> [C1] <span class="kwrd">FROM</span> ( <span class="kwrd">SELECT</span> <span class="kwrd">COUNT</span>(1) <span class="kwrd">AS</span> [A1] <span class="kwrd">FROM</span> [DomusDotNet].[Vehicles] <span class="kwrd">AS</span> [Extent1] <span class="kwrd">WHERE</span> N<span class="str">'110'</span> = <span class="kwrd">CAST</span>( [Extent1].[HP] <span class="kwrd">AS</span> nvarchar(<span class="kwrd">max</span>)) ) <span class="kwrd">AS</span> [GroupBy1]</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Da analizzare il funzionamento di “String.Concat(…)” con SQL Server 2012 per verificare la conversione in SQL con la funzione “nativa SQL” “<a href="http://technet.microsoft.com/en-us/library/hh231515.aspx" target="_blank">Concat</a>”.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101829.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx Thu, 27 Mar 2014 10:04:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/27/ef-6.1-whatrsquos-new-3.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101829.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101829.aspx EF 6.1 : What&rsquo;s new (2) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx <p>Altra <em>feature </em>introdotta, l’attributo “IndexAttribute” che ci permette di definire un indice su una o piu’ colonne. Ad esempio, per creare un indice (di nome “IX_FreeDailyKm”) sulla proprietà “FreeDailyKm” del nostro modello, scriviamo:</p> <pre class="csharpcode">[Index(<span class="str">"IX_FreeDailyKm_Clustered"</span>, IsUnique = <span class="kwrd">false</span>, IsClustered = <span class="kwrd">false</span>)] <span class="kwrd">public</span> <span class="kwrd">int</span> FreeDailyKm { get; set; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Mentre per creare un indice che insiste su due proprietà, è sufficiente utilizzare lo stesso nome come da esempio:</p> <pre class="csharpcode">[Index(<span class="str">"IX_Engine"</span>, 2)] <span class="kwrd">public</span> <span class="kwrd">string</span> EngineSize { get; set; } [Index(<span class="str">"IX_Engine"</span>, 1)] <span class="kwrd">public</span> <span class="kwrd">int</span> HP { get; set; }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Utilizzando <em>EF migrations</em> per aggiornare il database, avremmo:</p> <pre class="csharpcode">CreateIndex(<span class="str">"DomusDotNet.Vehicles"</span>, <span class="str">"FreeDailyKm"</span>, name: <span class="str">"IX_FreeDailyKm_Clustered"</span>); CreateIndex(<span class="str">"DomusDotNet.Vehicles"</span>, <span class="kwrd">new</span>[] { <span class="str">"HP"</span>, <span class="str">"EngineSize"</span> }, name: <span class="str">"IX_Engine"</span>);</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Quindi, a livello di database:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-2_EA92/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-2_EA92/image_thumb.png" width="244" height="55" /></a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101825.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx Thu, 20 Mar 2014 17:49:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-2.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101825.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101825.aspx EF 6.1 : What&rsquo;s new (1) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx <p>Da qualche giorno è stata rilasciata in RTM la <a href="http://blogs.msdn.com/b/adonet/archive/2014/03/17/ef6-1-0-rtm-available.aspx" target="_blank">versione 6.1.0</a> di Entity Framework. Una delle novità piu’ interessanti è sicuramente la possibilità di utilizzare l’approcio  <em>Code First </em>partendo da un database esistente (potrebbe sembrare strano, ma se pensiamo ad un nuovo sviluppo potrebbe non esserlo). I “ferri” da utilizzare sono ovviamente  EF 6.0.1 e la nuova versione di EF Tools, “scaricabile” per VS 2012 e VS 2013 seguendo <a href="http://www.microsoft.com/en-us/download/details.aspx?id=40762" target="_blank">questo</a> link.</p> <p>Per un semplice test, apriamo VS 2013 (o 2012), magari creando un semplice progetto “Console” al quale aggiungiamo tramite NuGet i riferimenti a EF 6.0.1. Poi tasto destro sul progetto e “Add New Item”, e scegliamo “ADO.NET Entity Data model”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_1.png" width="244" height="170" /></a></p> <p>Il testo di “Name” infuenzerà il nome della classe “DbContext” generata. Dalla scheramata successiva (“Entity Data Model Wizard”) scegliamo “Code First model from Database”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_2.png" width="244" height="170" /></a></p> <p>Nella schermata successiva del Wizard verrà chiesta la connessione dati da utilizzare (eventualmente ne creiamo una nuova), nel mio caso, per i test ho utilizzato un DB di un evento “DomusDotNet”. L’ultimo passo è la scelta degli oggetti da “importare”:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_8.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6.1--Whats-new-1_9B2C/image_thumb_3.png" width="244" height="219" /></a></p> <p>Dopo aver premuto “Finish” e qualche secondo di pazienza, VS aggiungerà all’alberatura del progetto, tutte le classi necessarie, una “buildata” per verificare che sia tutto a posto , e qualche riga di codice per verificare l’estrapolazione dati :</p> <pre class="csharpcode"><span class="kwrd">using</span> (CarRental db = <span class="kwrd">new</span> CarRental()) { System.Console.WriteLine(<span class="str">"There are {0} cars."</span>, db.Cars.Count()); System.Console.ReadKey(); }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101823.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx Thu, 20 Mar 2014 12:42:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/20/ef-6.1-whatrsquos-new-1.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101823.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101823.aspx Dynamic Data Provider per EF6 released http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx <p>Sono stati rilasciati in RTM, <em>ASP.NET Dynamic Data</em> e <em>EntityDataSource</em> per EntityFrameowrk 6. Per provare la nuova versione di <em>Dynamic Data</em> è sufficiente creare un nuovo progetto di tipo “ASP.NET Dynamic Data Entities Web Application”, ed installare tramite NuGet il package <em>Microsoft.AspNet.DynamicData.EFProvider</em>:</p> <p align="center"><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb.png" width="244" height="33" /></a></p> <p>Eventualmente forziamo la scrittura dei <em>Template</em> (“A” per sovrascrivere tutto):</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb_1.png" width="244" height="39" /></a></p> <p>Aggiungiamo in modalità <em>Code First</em> una semplice classe <em>Book </em>e relativo <em>DbContext</em>:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Book { <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Title { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Authors { get; set; } <span class="kwrd">public</span> <span class="kwrd">int</span> Pages { get; set; } } <span class="kwrd">public</span> <span class="kwrd">class</span> Db : DbContext { <span class="kwrd">public</span> DbSet&lt;Book&gt; Books { get; set; } <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnModelCreating(DbModelBuilder modelBuilder) { <span class="kwrd">base</span>.OnModelCreating(modelBuilder); } }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Nel <em>Global.asax</em> registriamo il nostro <em>DbContext</em>:</p> <pre class="csharpcode">DefaultModel.RegisterContext( <span class="kwrd">new</span> Microsoft.AspNet.DynamicData.ModelProviders.EFDataModelProvider(() =&gt; <span class="kwrd">new</span> Db()), <span class="kwrd">new</span> ContextConfiguration { ScaffoldAllTables = <span class="kwrd">true</span> });</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>F5, per vedere in azione il nostro <em>Data Site</em>:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/3b52774302cc_7140/image_thumb_2.png" width="244" height="156" /></a></p> <p>Discorso simile per l’utilizzo <em>dell’EntityDataSource</em> control.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101806.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx Mon, 03 Mar 2014 10:06:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/03/03/dynamic-data-provider-per-ef6-released.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101806.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101806.aspx ASP.NET Dynamic Data provider (preview) per EF6 http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/01/31/asp.net-dynamic-data-provider-preview-per-ef6.aspx <p>Rilasciato un aggiornamento per <em>ASP.NET DynamicData</em> e <em>DataSourceControl</em> per Entity Framework 6. Tutti i dettagli del caso sul <a href="http://blogs.msdn.com/b/webdev/archive/2014/01/30/announcing-preview-of-dynamic-data-provider-and-entitydatasource-control-for-entity-framework-6.aspx" target="_blank">blog originale</a>.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101763.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/01/31/asp.net-dynamic-data-provider-preview-per-ef6.aspx Fri, 31 Jan 2014 10:23:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2014/01/31/asp.net-dynamic-data-provider-preview-per-ef6.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101763.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101763.aspx EF : Relazione one-to-many Table-View http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/12/19/ef-relazione-one-to-many-table-view.aspx <p>Immaginiamo di avere un database SQL Server esistente, e vogliamo utilizzare Entity Framework Code First per mappare il modello dati. </p> <p>Supponendo di avere due tabelle “Items” e “Categories” in relazione come da <em>Database Diagram</em> seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/a8bf8935c20d_D16A/image_2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/a8bf8935c20d_D16A/image_thumb.png" width="244" height="94" /></a></p> <p>Ed una “Vista” SQL Server definita come segue:</p> <pre class="csharpcode"><span class="kwrd">CREATE</span> <span class="kwrd">VIEW</span> [dbo].[VCategories] <span class="kwrd">AS</span> <span class="kwrd">SELECT</span> Id, Name <span class="kwrd">FROM</span> Categories <span class="kwrd">WHERE</span> (Deleted = 0)</pre> <pre class="csharpcode"> </pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Aggiungiamo due classi C# definite in questo modo:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Category { <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Description { get; set; } }</pre> <p> </p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Item { <span class="kwrd">public</span> <span class="kwrd">int</span> Id { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Code { get; set; } <span class="kwrd">public</span> <span class="kwrd">string</span> Description { get; set; } <span class="kwrd">public</span> <span class="kwrd">int</span> CategoryId { get; set; } <span class="kwrd">public</span> Category Category { get; set; } }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>che mappiamo tramite <em>OnModelCreating (</em>nella classe derivata da <em>DbContext) </em>come segue :</p> <pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity&lt;Category&gt;().ToTable(<span class="str">"VCategories"</span>) .Property(c =&gt; c.Description).HasColumnName(<span class="str">"Name"</span>); modelBuilder.Entity&lt;Item&gt;().ToTable(<span class="str">"Items"</span>); modelBuilder.Entity&lt;Item&gt;().HasRequired(x =&gt; x.Category) .WithMany().HasForeignKey(o =&gt; o.CategoryId); }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Per verificare il funzionamento del <em>mapping</em> possiamo scrivere del codice tipo:</p> <pre class="csharpcode">Item item = <span class="kwrd">null</span>; <span class="kwrd">using</span> (Db db = <span class="kwrd">new</span> Db()) { Console.WriteLine(<span class="str">"Items count : {0}"</span>, db.Items.Count()); Category category = (from c <span class="kwrd">in</span> db.Categories <span class="kwrd">where</span> c.Id == 1 select c) .FirstOrDefault(); item = <span class="kwrd">new</span> Item() { Category = category, CategoryId = category.Id, Code = <span class="str">"Code #1"</span>, Description = <span class="str">"Description #1"</span>, }; db.Items.Add(item); db.SaveChanges(); Console.WriteLine(<span class="str">"Items count : {0}"</span>, db.Items.Count()); } <span class="kwrd">using</span> (Db db = <span class="kwrd">new</span> Db()) { <span class="rem">////Edit</span> item.Description = <span class="str">"New Description #1."</span>; db.Entry&lt;Item&gt;(item).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); Console.WriteLine(<span class="str">"Items count : {0}"</span>, db.Items.Count()); } <span class="kwrd">using</span> (Db db = <span class="kwrd">new</span> Db()) { <span class="rem">////Delete. </span> db.Entry&lt;Item&gt;(item).State = System.Data.Entity.EntityState.Deleted; db.SaveChanges(); Console.WriteLine(<span class="str">"Items count : {0}"</span>, db.Items.Count()); }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101747.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/12/19/ef-relazione-one-to-many-table-view.aspx Thu, 19 Dec 2013 16:55:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/12/19/ef-relazione-one-to-many-table-view.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101747.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101747.aspx EF6 RTM Available http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx <p>Con il rilascio di VS 2013, puntuale anche il rilascio in RTM di Entity Framework 6, tutti i dettagli direttamente sul blog di <a href="http://blogs.msdn.com/b/adonet/archive/2013/10/17/ef6-rtm-available.aspx#!" target="_blank">ADO.NET</a>.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101699.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx Thu, 17 Oct 2013 16:25:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/10/17/ef6-rtm-available.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101699.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101699.aspx EF 6 : Logging &amp; Interception http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/09/04/ef-6-logging-amp-interception.aspx <p> </p> <p>Una delle nuove feature introdotte nella versione 6 di Entity Framework (attualmente in RC) è il supporto al <em>logging</em> dell’SQL generato dal runtime di EF6. A tal fine è sufficiente passare un opportuno <em>delegate</em> alla proporietà <em>Log</em> esposta da <em>DbContext.Database</em>. Per gli esempi riprendiamo lo scenario del <a href="http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/19/ef6-beta-multiple-contexts-per-database-multi-tenant-migrations.aspx" target="_blank">post precedente</a>. </p> <p>Supponiamo di avere il seguente codice:</p> <pre class="csharpcode"> <span class="kwrd">using</span> (CarContext db = <span class="kwrd">new</span> CarContext()) { System.Console.WriteLine(<span class="str">"Cars in database : {0}"</span>, db.Cars.Count()); <span class="rem">////Add a new car.</span> Car car = <span class="kwrd">new</span> Car() { Brand = <span class="str">"Alfa Romeo"</span>, Model = <span class="str">"Giulietta"</span> }; db.Cars.Add(car); db.SaveChanges(); System.Console.WriteLine(<span class="str">"Cars in database : {0}"</span>, db.Cars.Count()); }</pre> <p /><style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Che banalmente visualizza il numero di auto (Cars) presenti nel  <em>repository</em>, ne aggiunge una e riesegue la conta delle auto registrate. Se volessimo analizzare l’SQL generato un ottimo strumento è sicuramete il SQL Profiler di SQL Server (che non dovrebbe mai mancare quando si lavora con un ORM <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Smile" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/wlEmoticon-smile_2.png" /> ), ma se utilizziamo EF6, ed il nostro obiettivo è semplicemente “scoprire\loggare” l’SQL generato da EF, possiamo modificare il codice precedente aggiungendo dopo la definizione del <em>DbContext,</em> la riga seguente:</p> <pre class="csharpcode"> db.Database.Log = Console.Write;</pre> <pre class="csharpcode"> </pre> <p>Dove la proprietà <em>Log</em> è cosi’ definita:</p> <pre class="csharpcode"><span class="kwrd">public</span> Action&lt;<span class="kwrd">string</span>&gt; Log { get; set; }</pre> <pre class="csharpcode"> </pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Eseguendo il codice della nostra applicazione dovremmo ottenere una “Console” simile alla seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_thumb.png" width="244" height="172" /></a></p> <p>Di default il log è molto chiaro in quanto ci restituisce il testo SQL del comando, quando è stato eseguito, il tempo impiegato, il tipo di risultato, gli eventuali parametri ed il tipo corrispondente. Possiamo ovviamente cambiare il contenuto e la formattazione del log secondo le nostre esigenze (e non solo) come vedremo piu’ avanti. Per come è definita la proprietà <em>Log</em>, qualsiasi funzione che accetta una stringa puo’ essere utilizzata per scrivere il nostro log. Quindi potremmo utilizzare un metodo tipo il seguente:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Log(<span class="kwrd">string</span> sql) { Console.WriteLine(<span class="str">"------------------------------------"</span>); Console.WriteLine(<span class="str">"SQL LOG: {0} "</span>, sql); Console.WriteLine(<span class="str">"------------------------------------"</span>); }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>oppure:</p> <pre class="csharpcode">System.IO.StreamWriter streamWriter = <span class="kwrd">new</span> System.IO.StreamWriter (fileStream, System.Text.ASCIIEncoding.ASCII ); db.Database.Log = sql =&gt; streamWriter.Write(sql);</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Per scrivere il log direttamente su file. Il concetto dovrebbe essere abbastanza chiaro. Vediamo come personalizzare la formattazione del log. </p> <p><em>Database.Log</em> non fa altro che utilizzare un ogetto <em>DatabaseLogFormatter </em>che a sua volta implementa le interfacce <em>IDbCommandInterceptor</em> e <em>IDbInterceptor </em>che sono rispettivamente l’interfaccia che permette di registrare un oggetto che possa ricevere notifiche da parte di Entity Framework quando un comando viene eseguito e l’interfaccia base per tutte le interfacce che permettono di fornire un <em>Interception Point</em> per differenti tipi di operazione.</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_thumb_1.png" width="134" height="244" /></a></p> <p>Quindi, per creare il nostro “Formattatore Custom” non ci resta che ereditare dalla classe <em>DatabaseLogFormatter</em> ed eseguire <em>l’override</em> dei metodi che ci interessano, come nel caso seguente:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> CustomLogFormatter : DatabaseLogFormatter { <span class="kwrd">public</span> CustomLogFormatter(DbContext context, Action&lt;<span class="kwrd">string</span>&gt; writeAction) : <span class="kwrd">base</span>(context, writeAction) { } <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> LogCommand&lt;TResult&gt;( DbCommand command, DbCommandInterceptionContext&lt;TResult&gt; interceptionContext) { Write(<span class="kwrd">string</span>.Format(<span class="str">"{0}{1}"</span>, <span class="str">"==============================================="</span>, Environment.NewLine)); Write(<span class="kwrd">string</span>.Format( <span class="str">"Context{2}{0}{2}Command{2}{1}{2}"</span>, Context.GetType().Name, command.CommandText.Replace(Environment.NewLine, <span class="str">""</span>), Environment.NewLine)); Write(<span class="kwrd">string</span>.Format(<span class="str">"{0}{1}"</span>, <span class="str">"==============================================="</span>, Environment.NewLine)); } }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p> </p> <p>Dove, l’<em>override</em> del metodo <em>LogCommand </em>esegue la formattazione del comando prima che questo sia eseguito da Entity Framework<em>. LogCommand</em> a sua volta  chiama eventualmente il metodo <em>LogParameter</em> per ogni parametro del comando, è necessario eseguire l’override di <em>LogParameter </em>per “customizzare” la formattazione del log dei paramateri. Infine, se vogliamo cambiare la formattazione del risultato, è necessario effettuare l’override di <em>LogResult. </em>Per interrompere l’esecuzione del comando, possiamo utilizzare il metodo :</p> <pre class="csharpcode">interceptionContext.SuppressExecution()</pre> <pre class="csharpcode"> </pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Nel corpo dell’<em>override</em> di <em>LogCommand. </em>Per vedere in “funzione” il nostro “Formatter” è sufficiente registrare l’istanza di <em>CustomLogFormatter</em> tramite una classe derivata da <em>DbConfiguration</em> presente nello stesso assembly che contiene la definizione del <em>DbContext:</em></p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> MyDbConfiguration : DbConfiguration { <span class="kwrd">public</span> MyDbConfiguration() { SetDatabaseLogFormatter( (context, writeAction) =&gt; <span class="kwrd">new</span> CustomLogFormatter(context, writeAction)); } }</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Eseguendo, otteniamo il “nostro” log:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/EF-6--Logging--Interceptor_6F20/image_thumb_2.png" width="244" height="118" /></a></p> <p>Per approfondimenti:</p> <p><a title="https://entityframework.codeplex.com/wikipage?title=Interception" href="https://entityframework.codeplex.com/wikipage?title=Interception" target="_blank">Entity Framework Codeplex</a></p> <p><a href="http://blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/" target="_blank">One Unicorn: EF6 SQL Logging</a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101658.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/09/04/ef-6-logging-amp-interception.aspx Wed, 04 Sep 2013 15:15:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/09/04/ef-6-logging-amp-interception.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101658.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101658.aspx Disponibile EF 6 RC http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx <p>Rilasciata la RC di Entity Framework 6, tutti i dettagli e le novità rispetto alla Beta 1, <a href="http://blogs.msdn.com/b/adonet/archive/2013/08/21/ef6-release-candidate-available.aspx" target="_blank">qui</a>. </p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101644.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx Thu, 22 Aug 2013 09:25:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/22/disponibile-ef-6-rc.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101644.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101644.aspx EF6 (beta) : Multiple Contexts per Database, Multi-Tenant Migrations http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/19/ef6-beta-multiple-contexts-per-database-multi-tenant-migrations.aspx <p>Una delle novità introdotte con EF6 è la possibilità di gestire molteplici modelli per singola istanza di database, che non vuol dire usare lo stesso contesto piu’ volte nello stesso database, ma poter utilizzare Entity Framework Migrations e relativa Migration History Table per gestire la migrazione di due o piu’ modelli per singolo database fisico. Specifichiamo questa <em>feature</em> come <em>Multi-Tenant Migrations</em>.</p> <p>Come esempio, supponiamo di avere due classi <em>Bus</em> e <em>Car</em> facenti parte dello stesso <em>Domain</em> di una nostra applicazione, ma interessate da due <em>DbContext </em>diversi, rispettivamente <em>BusContext</em> e <em>CarContext</em>, come da <em>Class Diagram</em> seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_16.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb.png" width="244" height="62" /></a></p> <p>Provando ad abilitare EF Migrations per il progetto corrente, essendo presenti due <em>DbContext</em>, il “Package Manager Console” risponderebbe restituendo l’errore seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_1.png" width="244" height="72" /></a></p> <p>Vediamo come utilizzare <em>Multi-Tenant Migrations</em>: iniziamo ad utilizzare la prima delle novità di EF6 (migrations), l’opzione “-MigrationDirectory” che ci permette di specificare, insieme all’opzione “-ContextTypeName” che rispettivamente indicano dove far risiedere i piani di migrazione e quale <em>DbContext</em> considerare. Il comando completo da utilizzare diventa quindi:</p> <p><em>PM&gt;Enable-Migrations -MigrationsDirectory BusDbContextMigration -ContextTypeName MultiTenantMigration.BusContext</em></p> <p>Questa volta tutto fila liscio, ottenendo un messaggio di questo tipo:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_2.png" width="244" height="39" /></a></p> <p>Il “Solution Explorer” dovrebbe apparire simile alla figura seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_8.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_3.png" width="244" height="175" /></a></p> <p>Visualizziamo il codice della classe <em>Configuration.cs</em> e modifichiamolo opportunatamente impostando la proprietà <em>ContextKey</em> che altro non è una nuova proprietà di configurazione per EF6 Migrations che aggiunge nella “_MigrationHistory Table” una nuova colonna che rende possibile la funzionalità “Multi-Tenant”:</p><pre class="csharpcode"><span class="kwrd">public</span> Configuration() { ContextKey = <span class="str">"BusContextKey"</span>; AutomaticMigrationsEnabled = <span class="kwrd">false</span>; MigrationsDirectory = <span class="str">@"BusDbContextMigration"</span>; }</pre><pre class="csharpcode"> </pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Come prima, eseguiamo le operazioni precedenti per abilitare la migrazione anche per il <em>DbContext </em>“CarContext” ottenendo un “Solution Explorer” simile al seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_10.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_4.png" width="244" height="160" /></a></p> <p>E per <em>Configuration.cs</em>:</p><pre class="csharpcode"><span class="kwrd">public</span> Configuration() { ContextKey = <span class="str">"CarContext"</span>; AutomaticMigrationsEnabled = <span class="kwrd">false</span>; MigrationsDirectory = <span class="str">@"CarDbContextMigration"</span>; }</pre><pre class="csharpcode"> </pre> <p>Aggiungiamo i corrispettivi piani di migrazione:</p> <p><em>PM&gt; Add-Migration CarDbMigration -ConfigurationTypeName MultiTenantMigration.CarDbContextMigration.Configuration <br />Scaffolding migration 'CarDbMigration'</em></p> <p><em>PM&gt; Add-Migration BusDbMigration -ConfigurationTypeName MultiTenantMigration.BusDbContextMigration.Configuration <br />Scaffolding migration 'BusDbMigration'</em></p> <p>Procediamo con l’aggiornamento del database (ricordiamo essere lo stesso per i due <em>DbContext</em>). Procediamo con <em>CarDbContext</em>:</p> <p><em>PM&gt; Update-Database -ConfigurationTypeName MultiTenantMigration.CarDbContextMigration.Configuration <br />Specify the '-Verbose' flag to view the SQL statements being applied to the target database. <br />Applying explicit migrations: [201308141834283_CarDbMigration]. <br />Applying explicit migration: 201308141834283_CarDbMigration. <br />Running Seed method.</em></p> <p>Il messaggio indica che l’aggiornamento è stato completato con successo. Passiamo ora a <em>BusDbContext</em>:</p> <p><em>PM&gt; Update-Database -ConfigurationTypeName MultiTenantMigration.BusDbContextMigration.Configuration <br />Specify the '-Verbose' flag to view the SQL statements being applied to the target database. <br />Applying explicit migrations: [201308141835410_BusDbMigration]. <br />Applying explicit migration: 201308141835410_BusDbMigration.<br />Running Seed method.</em></p> <p>A livello database:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_12.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_5.png" width="244" height="114" /></a></p> <p>In dettaglio, la tabella “MigrationHistory” è popolata con le seguenti righe (da notare la colonna <em>ContextKey</em>):</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_14.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/8d783d8054a5_11B93/image_thumb_6.png" width="244" height="37" /></a></p> <p>A questo punto, tutte le successive modifiche al modello, ed i relativi piani di migrazione dovrebbero essere applicati con successo.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101641.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/19/ef6-beta-multiple-contexts-per-database-multi-tenant-migrations.aspx Mon, 19 Aug 2013 09:38:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2013/08/19/ef6-beta-multiple-contexts-per-database-multi-tenant-migrations.aspx#feedback 1 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101641.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101641.aspx