posts - 315, comments - 268, trackbacks - 15

My Links

News

View Pietro Libro's profile on LinkedIn

DomusDotNet
   DomusDotNet

Pietro Libro

Tag Cloud

Article Categories

Archives

Post Categories

Blogs amici

Links

EF CTP5 : The End :-)

E’ da un po’ di tempo che volevo chiudere questa serie, forse questa sera ci riesco Sorriso. A differenza del titolo, questo post farà riferimento alla versione RC di Entity Framework 4.1, ma per essere coerenti è necessario qualche nota su come rendere “utilizzabile” per questa versione il codice degli esempi precedenti (scritti per la CTP 5):

1) Disinstallazione della versione CTP5 di Entity Framework

2) Installazione della versione RC (scaricabile come pacchetto stand alone all’indirizzo: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2dc5ddac-5a96-48b2-878d-b9f49d87569a&displaylang=en)

3) Sostituzione della reference alla nuova libreria EntityFramework.dll

4) Cambiare la firma di OnModelCreating in : OnModelCreating(DbModelBuilder modelBuilder)

5) Rimozione di Using System.Data.Entity.Database; ed aggiunta di using System.Data.Entity.ModelConfiguration.Configuration;

6) Sostituzione di context.Database.SqlCommand con context.Database.ExecuteSqlCommand

7) Nelle Fluent API, ove necessario, sostituzione di  m => m.MapKey(d=>d.Id, "SviluppatoreId") con m => m.MapKey("SviluppatoreId")

I punti precedenti fanno riferimento a come “migrare” il codice dei post precedenti della serie. Per maggiori dettagli sulla migrazione del codice dalla versione CTP5 per tutti i casi è possibile consultare il blog del team di ADO.NET.

Concludiamo la serie con qualche scenario di mapping (dato che oramai è inutile parlare delle Pluggable Conventions). Supponiamo di avere un Object Model come rappresentato dal Class Diagram seguente:

image

 

Table-per-hierarchy (TPH)

Questa strategia di mapping prevede che un’intera gerarchia di oggetti .NET sia mappata su una singola tabella di database. In questo caso abbiamo un campo discriminante che permette di eseguire la distinzione tra i vari tipi di oggetto. Applichiamo questo caso alle classi Subject, Customer e Supplier, in codice:

modelBuilder.Entity<Subject>()
    .Ignore(p => p.Type);

modelBuilder.Entity<Customer>()
    .Map(mc =>
    {
        mc.Requires("Type").HasValue<byte>(1);
    });

modelBuilder.Entity<Supplier>()
    .Map<Supplier>(mc =>
    {
        mc.Requires("Type").HasValue<byte>(2);
    });

In questo modo, la classe Subject deve esporre una proprietà, Type, di tipo byte, mappata sulla colonna “discriminante”. Nel caso non volessimo avere questa incombenza è sufficiente rimuovere la proprietà Type dalla classe Subject e commentare le righe:

modelBuilder.Entity<Subject>()
    .Ignore(p => p.Type);

Tra le classi BaseClass (classe da cui derivano tutte le altre classi nel nostro modello ad oggetti) e Subject applichiamo invece una strategia

Table-per-Type (TPT)

Dove a differenza del caso precedente, ogni classe è mappata su una specifica tabella di database. E’ il caso più semplice, è sufficiente utilizzare la Fluent API ToTable come in questo caso:
modelBuilder.Entity<BaseClass>()
    .HasKey(p => p.Id)
    .ToTable("BaseObjects");

modelBuilder.Entity<Subject>()
    .ToTable("Subjects");

Per terminare, tra Customer e SpecialCustomer utilizziamo una strategia

Table-per concrete-type (TPC)

Dove ogni tipo della gerarchia di oggetti è mappata in una specifica tabella contenente tutte le proprietà dello specifico tipo anche nel caso in cui derivino da uno stesso tipo base (come nell’esempio). In questi casi utilizziamo la fluent MapInheritedProperties, come nel codice seguente:

modelBuilder.Entity<SpecialCustomer>()
    .Map(m => m.MapInheritedProperties())
    .ToTable("SpecialCustomers");

Il risultato finale del mapping è riassunto nel seguente diagramma di database:

image

Una diversa strategia di mapping tra Customers e SpecialCustomers potrebbe essere la seguente:

modelBuilder.Entity<Customer>()
    .Map(m =>
    {
        m.Properties(p => new
        {
            p.Id,
            p.IdCode,
            p.Inserted,
            p.Nominative,
            p.UserId,
            p.Updated
        });
    })
    .ToTable("Customers");

modelBuilder.Entity<SpecialCustomer>()
    .Map(m => { m.Properties(p => new { p.Discount }); }).ToTable("SpecialCustomers");

la quale creerebbe un diagramma di database di questo tipo:

image

Quest’ultima strategia, mappata su di una stessa Entità (Customer ad esempio) può essere utilizzata per “spalmare” un tipo su più tabelle di database (Entity Splitting). Gli scenari esposti in questo post possono dare un’idea delle principali strategie di mapping che possiamo utilizzare nella progettazione delle nostre applicazioni. Durante la serie abbiamo principalmente trattato l’approccio Code First, ma bisogna considerare che le novità introdotte, come ad esempio il supporto alla validazione, con la RC di Entity Framework possono essere utilizzate anche con i “classici” approcci Database First e Model First.

Print | posted on martedì 22 marzo 2011 00:45 | Filed Under [ Entity Framework 4.1 ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET