<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Entity Framework 4</title>
        <link>http://blogs.ugidotnet.org/pietrolibroblog/category/Entity Framework 4.aspx</link>
        <description>Entity Framework 4</description>
        <language>it-IT</language>
        <copyright>Pietro Libro</copyright>
        <managingEditor>pietro.libro@libero.it</managingEditor>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>EF6 (beta1) - Code First Stored Procedures Mapping</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2013/06/26/ef6-beta1-code-first-stored-procedures-mapping.aspx</link>
            <description>Una delle features che sicuramente in molti aspettavano con la nuova release di EF è la possibilità di eseguire il mapping delle entità tramite Stored Procedures. Con la versione 6 di Entity Framework (attualmente in beta 1), abbiamo finalmente questa possibilità, e l'utilizzo è veramente immediato.  Supponiamo di avere un Domain Model simile a quello mostrato nella figura seguente:     Dove abbiamo un insieme di oggetti ereditati, ed una navigation property che collega l'oggeto Car ad una collezione di oggetti Optional.   Aggiungiamo il riferimento ad EF6 utilizzando il gestore di "NuGet Packages" selezionando tra le varie opzioni "Include Prerelease" e poi selezioniamo il package "Entity Framework":     Eseguiamo la configurazione delle classi che compongono il nostro Domain tramite Code First Fluent Api ed aggiungiamo il codice seguente:   modelBuilder.Entity&amp;lt;Domain.Car&amp;gt;().MapToStoredProcedures();
 modelBuilder.Entity&amp;lt;Domain.Optional&amp;gt;().MapToStoredProcedures();

 

Il quale "informa" il run-time di Entity Framework che per le entità "Car" ed "Optional" le operazioni di Insert\Delete\Update verranno utilizzate delle Stored Procedures (che rispondono alle convenzioni richieste da EF). 

A questo punto entra in scena EF Migrations ed il "fantastico" comando "Add-Migration", che produce tutto il codice, e non solo, necessario ad aggiornare il database:

 public override void Up()
        {
            CreateStoredProcedure(
                "DomusDotNet.Car_Insert",
                p =&amp;gt; new
                    {
                        Brand = p.String(maxLength: 128),
                        Model = p.String(maxLength: 128),
                        EngineSize = p.String(maxLength: 128),
                        HP = p.Int(),
                        DailyRent = p.Single(),
                        FreeDailyKm = p.Int(),
                        Note = p.String(maxLength: 128),
                    },
                body:
                    @"INSERT [DomusDotNet].[Vehicles]([Brand], [Model], [EngineSize], [HP], [DailyRent], [FreeDailyKm], [Note])
                      VALUES (@Brand, @Model, @EngineSize, @HP, @DailyRent, @FreeDailyKm, @Note)
                      
                      DECLARE @Id int
                      SELECT @Id = [Id]
                      FROM [DomusDotNet].[Vehicles]
                      WHERE @@ROWCOUNT &amp;gt; 0 and [Id] = scope_identity()
                      
                      INSERT [DomusDotNet].[Cars]([Id])
                      VALUES (@Id)
                      
                      SELECT t0.[Id]
                      FROM [DomusDotNet].[Vehicles] as t0
                      WHERE @@ROWCOUNT &amp;gt; 0 and t0.[Id] = @Id"
            );
            
           ...


Unico neo, se utilizzate uno schema diverso da "dbo" (anche se avete specificato tramite la nuova API HasDefaultSchema("...") lo schema corretto) bisogna modificare manualmente il nome delle Stored Procedures, altrimenti a run-time verrà generata un'eccezione.

Scriviamo del codice di test tipo:

int rowsAffected = 0;

Domain.Car fordFocus = new Domain.Car()
{
    Brand = "FORD",
    DailyRent = 45.0f,
    EngineSize = "1600",
    FreeDailyKm = 100,
    HP = 115,
    Model = "Focus",
    Note = "With Radio and Power Steering."
};

fordFocus.Optionals.Add(new Domain.Accesory() { Description = "Radio Sony", Removable = true, Price = 10 });
fordFocus.Optionals.Add(new Domain.Accesory() { Description = "Power Steering", Removable = false, Price = 0 });

using (Data.CarRentalDB db = new Data.CarRentalDB())
{
    db.Cars.Add(fordFocus);
    rowsAffected = db.SaveChanges();
}

Utilizzando il nostro amico "Sql Profiler" vediamo come le operazioni di accesso alla tabella per Insert\Update\Delete utilizzano le Stored Procedures generate in precedenza:

 

Di questo ed altro parleremo in dettaglio durante l'evento EF@Work organizzato da DomusDotNet :-)&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/101596.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2013/06/26/ef6-beta1-code-first-stored-procedures-mapping.aspx</guid>
            <pubDate>Wed, 26 Jun 2013 10:30:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2013/06/26/ef6-beta1-code-first-stored-procedures-mapping.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/101596.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/101596.aspx</trackback:ping>
        </item>
        <item>
            <title>EF Power Tools Beta 2: Prove su strada</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/04/11/ef-power-tools-beta-2-prove-su-strada.aspx</link>
            <description>Ero troppo curioso di provare la nuova versione (beta) dei Tools per EF. Diciamo che la curiosità è stata parzialmente ripagata  dato che con la prima versione non riuscii  a fare granché essendo, almeno nella mia configurazione software, non molto stabile. Andiamo con ordine: dopo aver installato la nuova versione dei Tools, ho provato subito ad eseguire la funzione “Reverse Engineer Code First”  (disponibile come voce di menu contestuale selezionando un progetto C#).    Per l’esperimento ho scelto un database con diverse tabelle, relazioni e “gerarchie”. Dopo aver cliccato sulla voce precedente, VS ha iniziato a “macinare” generando una sfilza di classi, suddividendole opportunatamente in classi di Mapping, Object Model e DbContext:      L’operazione è durata pochi secondi. Secondo il post del team di ADO.NET EF, VS avrebbe dovuto scaricare ed installare (se non già presente nel progetto) l’ultima versione di Entity Framework (nello specifico caso non è accaduto, ma con NuGet, anche questa operazione è durata poco  ). Scorrendo l’elenco delle classi generate noto come il processo di reverse engineering abbia creato delle classi anche per le tutte le viste presenti sul database. Proviamo ad analizzare “graficamente” il modello ad oggetti creato, selezionando nel Solution Explorer la classe derivata dal DbContext e poi la voce “View Entity Data Model (Read Only)”:      Molte delle classi “isolate” sono proprio le classi\viste generate dal VS. Con le altre opzioni disponibili possiamo, creare il DDL SQL:      e visualizzare l’Entity Data Model XML:      Se siamo curiosi, possiamo creare un nuovo database a partire dalle classi generate da VS e poi eseguire uno Schema Compare per visionare le differenze tra l’originale ed il generato:                                   A colpo d’occhio mancano, rispetto all’originale, Stored Procedure e Viste, poi analizzando nel dettaglio le varie tabelle possiamo trovare alcune differenze come VARCHAR in NVARCHAR, valori di default mancanti, campi TEXT trasformati in NVARCHAR(MAX). Riassumendo, i Tools sembrano essere abbastanza stabili (rispetto alla versione precedente nessun crash ) , quello che è certo (almeno fino ad ora) che dovendo partire da un database esistente, sviluppare le classi POCO e DbContext con questa rapidità non ha prezzo, ma sicuramente è necessario un ulteriore lavoro di “fino” (magari in combinazione con EF Code First Migrations) se l’obiettivo è quello di avere un modello finale “fedele” all’originale, in caso contrario è un ottima base di partenza per un refactoring.&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100945.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/04/11/ef-power-tools-beta-2-prove-su-strada.aspx</guid>
            <pubDate>Wed, 11 Apr 2012 07:53:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/04/11/ef-power-tools-beta-2-prove-su-strada.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100945.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100945.aspx</trackback:ping>
        </item>
        <item>
            <title>DomusDotNet : We Want Web, grazie a tutti :-)</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx</link>
            <description>Ieri 9/3/12 si è svolto l’evento WeWantWeb organizzato da DomusDotNet presso la sede Microsoft di Roma. Le sessioni sono state registrare e quanto prima pubblicheremo Slide, codice sorgente degli esempi e Video, sul sito di DomusDotNet. Grazie a tutti i partecipanti!!! Attendiamo i vostri feedback! Al prossimo evento .    Da sinistra verso destra: Alessandro Mostarda e Massimo Bonanni, Giorgio Di Nardo, Nick, io , parte di coloro che hanno avuto la pazienza di ascoltarci .&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100854.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx</guid>
            <pubDate>Sat, 10 Mar 2012 20:52:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/03/10/domusdotnet-wewantweb-grazie-a-tutti.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100854.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100854.aspx</trackback:ping>
        </item>
        <item>
            <title>EF 4.3 Released</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/02/10/ef-4.3-released.aspx</link>
            <description>Rilasciata la versione 4.3 di Entity Framework, tra le novità introdotte in questa release, il più interessante IMHO il supporto all’evoluzione di un database generato utilizzando l’approccio Code First. Installazione semplice ed indolore tramite NuGet  : Install-Package EntityFramework. Per il supporto agli Enum bisognerà aspettare la versione 5.0 (.Net 4.5). Tutti i dettagli sul post dell’ ADO.NET Team: http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-released.aspx&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100765.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/02/10/ef-4.3-released.aspx</guid>
            <pubDate>Fri, 10 Feb 2012 08:21:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2012/02/10/ef-4.3-released.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100765.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100765.aspx</trackback:ping>
        </item>
        <item>
            <title>DomusDotNet: WCF Data Services (Prima parte)</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx</link>
            <description>Prima parte di una serie di articoli dedicati ai WCF Data Services, al protocollo OData e REST. Per gli interessati , articolo completo qui. &lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100645.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx</guid>
            <pubDate>Wed, 21 Dec 2011 01:00:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/21/domusdotnet-wcf-data-services-prima-parte.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100645.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100645.aspx</trackback:ping>
        </item>
        <item>
            <title>EF Code First Migrations Beta 1 (Parte 2)</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/04/ef-code-first-migrations-beta-1-parte-2.aspx</link>
            <description>In questa seconda parte proveremo ad eseguire gli stessi passi eseguiti in precedenza utilizzando “la migrazione automatica dello schema”. Per comodità riporto la classe DbContext ed il semplice Object Model utilizzato per la definizione dello schema del database:   public class OfficeContext : DbContext
    {
        public OfficeContext()
            : base("OfficeDB")
        {
        }
        public DbSet&amp;lt;Employee&amp;gt; Employees { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
        static OfficeContext()
        {
            Database.SetInitializer&amp;lt;OfficeContext&amp;gt;(null);
        }
    }
    public class Employee
    {
        public int Id { get; set; }
        public String Name { get; set; }
        public String Surname { get; set; }
        public String Role { get; set; }
    }


Avendo aggiunto EntityFramework.Migrations in precedenza, per continuare, dobbiamo aprire la classe Configuration.cs all’interno della cartella Migrations ed impostare la proprietà AutomaticMigrationsEnabled a true:

public Configuration()
{            
    AutomaticMigrationsEnabled = true;
    AutomaticMigrationDataLossAllowed = false;
}

Inoltre impostiamo la proprietà AutomaticMigrationDataLossAllowed=false: in questo modo un’eccezione verrà sollevata nel caso in cui la migrazione dello schema comporti una perdita di dati. Nell’override del metodo Seed aggiungiamo del codice per inserire delle righe dopo la generazione\migrazione dello schema:

protected override void Seed(OfficeContext context)
{            
    context.AddOrUpdate(
        new Employee() { Name = "Mario", Surname = "Rossi", Role = "Administrator" },
        new Employee() { Name = "Giulio", Surname = "Verdi", Role = "Store Manager" },
        new Employee() { Name = "Pietro", Surname = "Libro", Role = "Art Director" }
        );
}

A differenza della procedura manuale, digitiamo direttamente il comando update-database nella console di NuGet, eventualmente utilizzato i parametri –verbose  o -script rispettivamente per visualizzare o creare un file di .sql con i comandi generati da VS:



Come per la prima parte, utilizzando ad esempio SQL Management Studio, vediamo che il lavoro “sporco” sia stato eseguito correttamente come ci aspettavamo:



Ora, se volessimo apportare le stesse modifiche allo schema del modello dati, come nel caso del post precedente, dovremmo ritornare “in modalità manuale” (in quanto, in questa modalità non possiamo specificare i valori di default per i nuovi campi o utilizzare codice SQL custom) quindi  utilizzando il comando Add-Migration e relativi parametri. Ovviamente abbiamo già discusso su come eseguire questi passaggi e non staremo qui a ripeterli:  IMHO la migrazione automatica non mi ha entusiasmato molto a differenza di quella manuale dove è possibile intervenire in diversi punti.

Proviamo ora ad eliminare (o commentare) la proprietà Surname  dall’entità Employee:

    public class Employee
    {
        public int Id { get; set; }
        public String Name { get; set; }
        public String Role { get; set; }
    }


Commentiamo il codice presente nel Seed ed eseguiamo il comando update-database:



Entity Framework ci avverte che l’aggiornamento non è stato completato perché potrebbe verificarsi una perdita di dati, ma allo stesso tempo ci suggerisce di utilizzare il parametro –force per forzare l’aggiornamento della base di dati (con conseguente data loss). Ok.

Oltre a commentare il codice (non proprio una best practice) per evitare di aggiungere dati duplicati tramite l’AddOrUpdate del Seed  è sufficiente istruire VS con una Func&amp;lt;TEntity,Object&amp;gt; al fine di specificare quali proprietà devono essere considerate per identificare un record come duplicato:

System.Linq.Expressions.Expression&amp;lt;Func&amp;lt;Employee, object&amp;gt;&amp;gt; identify =
    n =&amp;gt; new { n.Name, n.Role  };

context.AddOrUpdate(identify,
    new Employee() { Name = "Mario", Role = "Administrator" },
    new Employee() { Name = "Giulio", Role = "Store Manager" },
    new Employee() { Name = "Pietro", Role = "Art Director" }
    );
&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100600.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/04/ef-code-first-migrations-beta-1-parte-2.aspx</guid>
            <pubDate>Sun, 04 Dec 2011 08:42:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/12/04/ef-code-first-migrations-beta-1-parte-2.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100600.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100600.aspx</trackback:ping>
        </item>
        <item>
            <title>Ed anche&amp;hellip;</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/09/07/ed-anchehellip.aspx</link>
            <description>…la 70-516 : Accessing Data with Microsoft .NET Framework 4 è andata. Adesso un paio di settimane di riposo e poi si ricomincia &lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100328.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/09/07/ed-anchehellip.aspx</guid>
            <pubDate>Wed, 07 Sep 2011 13:14:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/09/07/ed-anchehellip.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100328.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100328.aspx</trackback:ping>
        </item>
        <item>
            <title>EF 4.2 Beta 1</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/08/22/ef-4.2-beta-1.aspx</link>
            <description>Come preannunciato è disponibile la Beta 1 di Entity Framework, disponibile via NuGet. Maggiori dettagli qui.&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/100289.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/08/22/ef-4.2-beta-1.aspx</guid>
            <pubDate>Mon, 22 Aug 2011 19:24:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/08/22/ef-4.2-beta-1.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/100289.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/100289.aspx</trackback:ping>
        </item>
        <item>
            <title>EF 4.1 Release Candidate Available</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/16/ef-4.1-release-candidate-available.aspx</link>
            <description>Dal blog del team di ADO.NET  http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-release-candidate-available.aspx&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/99842.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/16/ef-4.1-release-candidate-available.aspx</guid>
            <pubDate>Wed, 16 Mar 2011 17:17:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/16/ef-4.1-release-candidate-available.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/99842.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/99842.aspx</trackback:ping>
        </item>
        <item>
            <title>EF 4.1 Is Coming!</title>
            <link>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/03/ef-4.1-is-coming.aspx</link>
            <description>Non condivido alcune scelte come l’eliminazione delle Pluggable Conventions (erano molto comode).  Interessante il supporto della validazione anche nella modalità Model First e Database First.  Tutti i dettagli nell’ultimo post del blog dell’ADO.NET Team:   http://blogs.msdn.com/b/adonet/archive/2011/03/02/ef-4-1-is-coming-dbcontext-api-amp-code-first-rtw.aspx  Vedremo.&lt;img src="http://blogs.ugidotnet.org/pietrolibroblog/aggbug/99775.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pietro Libro</dc:creator>
            <guid>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/03/ef-4.1-is-coming.aspx</guid>
            <pubDate>Thu, 03 Mar 2011 17:22:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/pietrolibroblog/archive/2011/03/03/ef-4.1-is-coming.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/pietrolibroblog/comments/commentRss/99775.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/pietrolibroblog/services/trackbacks/99775.aspx</trackback:ping>
        </item>
    </channel>
</rss>