Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Entity Framework

Sftuttare la potenza dell'ORM per creare e manipolare gli elementi del database come se fossero oggetti in memoria
Sftuttare la potenza dell'ORM per creare e manipolare gli elementi del database come se fossero oggetti in memoria
Link copiato negli appunti

L'ultima tecnologia di accesso dati che esaminiamo è Entity Framework, introdotta nel .NET 3.5 SP1, è la più recente tra tutte quelle viste fino ad ora. La prima versione era piuttosto acerba rispetto ad ORM più navigati come NHibernate, ma nella versione 4.0 inclusa in VS2010 sono state introdotte moltissime feature che la rendono decisamente interessante.

L'approccio adottato da Entity Framework è in linea di massima quello di un ORM ed è un prodotto che si trova quindi in una posizione più o meno analoga a quella di Nhibernate. Sebbene come già detto la prima versione non può essere a tutti gli effetti considerata un ORM, in questa seconda versione l'approccio è decisamente molto più ORM-like.

Una trattazione completa di EF occuperebbe un testo intero, in questa guida faremo solo una breve panoramica per comprendere in linea di massima le differenze tra Entity Framework e un approccio mediante DataSet.

Per usare EF è sufficiente inserire nel progetto un ADO.NET Entity Data Model. Visual Studio apre a questo punto un wizard che permette di creare un modello in modo semplice, ad esempio partendo da un database esistente. In questo caso, Entity Framework presenta una finestra in cui sono listati tutti gli oggetti del db che è possibile utilizzare (tabelle, viste e stored procedure) ed è possibile scegliere gli oggetti che si vuole gestire.

Figura 5. Selezionare le tabelle da importare nella struttura EF
Selezionare le tabelle da importare nella struttura EF

In questa nuova versione è possibile generare il database con Entity Framework in modo visuale con un approccio "Designer First": non si parte da un DataBase preesistente, ma si iniziano a disegnare gli oggetti nel designer lasciando poi ad EF il compito di generare un database che è in grado di persistere gli oggetti creati.

Selezionando invece un database esistente, come northwind e scegliendo di importare tutte le tabelle e viste, il risultato è un designer simile a quello del DataSet in cui sono rappresentate tutte le tabelle e le viste importate, con le varie relazioni tra gli oggetti.

Figura 6. Il designer di Entity Framework
Il designer di Entity Framework

La principale differenza rispetto ad un Dataset è nell'interrogazione del database la possiamo osservare nel seguente spezzone di codice, usato per recuperare tutti i clienti che vivono in una città che contiene la stringa "GA" nel nome e mostrare alcuni dettagli degli ordini.

using (northwindEntities context = new northwindEntities())
{
  var customers = from Customers c in context.Customers
                  where c.City.Contains("GA")
                  select c;
  foreach (var customer in customers)
  {
    Console.WriteLine("Orders for customer: {0} living in city {1}",
                      customer.CustomerID, customer.City);
    foreach (Orders order in customer.Orders)
    {
      Console.WriteLine("Order id: {0,2}, date {1}", order.OrderID, order.OrderDate);
    }
  }
}

Molti sono gli aspetti interessanti: in primo luogo i dati sono stati filtrati con una query LINQ impostando quindi le condizioni direttamente sulle proprietà degli oggetti. Come si può notare la condizione di vivere in una città il cui nome contiene la stringa "GA" viene effettuata con c.City.Contains("GA"), usando quindi il metodo Contains() dell'oggetto System.String proprio come se gli oggetti di tipo Customers fossero contenuti in una collection in memoria.

Il risultato memorizzato nella variabile customers è un oggetto specifico di EF che implementa l'interfaccia IQueryable<> e che può essere enumerato con un istruzione foreach. Dietro le quinte, durante l'enumerazione, questo oggetto traduce la query LINQ in istruzioni SQL, apre la connessione, effettua la query, recupera i dati e ricrea in memoria gli oggetti partendo dai dati restituiti dalla query.

Questa è infatti la prima caratteristica di un ORM: permettere all'utente di interagire con gli oggetti senza avere la minima conoscenza di come gli oggetti saranno poi persistiti nel database.

L'altro aspetto interessante è che per scorrere la lista degli ordini di un cliente, si è semplicemente acceduto alla sua proprietà Orders senza effettuare nessuna ulteriore query esplicita. Questa funzionalità è chiamata Lazy Load e consiste in un auto caricamento dei dati effettuato al momento dell'accesso ad una collection o proprietà. Se si utilizza il profiler di Sql Server per visualizzare le query effettuate al database, si può vedere come al momento della prima iterazione del foreach viene effettuata la query che recupera i clienti, mentre ogni volta che si accede alla proprietà Orders di un oggetto Customers viene effettuata la query relativa che recupera gli ordini.

Questo primo banale esempio fa immediatamente capire che l'approccio usato in questo caso è molto differente dal TableModule visto in precedenza, e ci stiamo spostando infatti verso una logica di business basata su Domain Model.

Grazie a EF le modifiche agli oggetti sono tracciate in maniera automatica, per cambiare una proprietà di un cliente è sufficiente utilizzare questo semplice spezzone di codice.

using (northwindEntities context = new northwindEntities())
{
  var ALFKI = context.Customers.Where(c => c.CustomerID == "ALFKI").Single();
  ALFKI.CompanyName += "_";
  context.SaveChanges();
}

Il vantaggio nell'uso di un ORM è il poter lavorare con oggetti in memoria e lasciare che sia l'ORM a occuparsi di propagare i cambiamenti nel database in maniera completamente trasparente; nel contesto di EF è infatti presente il metodo SaveChanges che si occupa di controllare tutte le proprietà modificate di ogni oggetto e propagare i cambiamenti al database.

Uno degli altri vantaggi nell'uso di EntityFramework è costituito dai WCF Data Service. Inserendo un oggetto di tipo WCF Data Service in una web application viene infatti creato uno scheletro vuoto di servizio WCF per accedere ai dati. La configurazione minima che si può fare è quella di specificare il modello Entity Framework da usare e scegliere quali entità gestire e con che livello di accesso. Nell'esempio sottostante si è ad esempio scelto di gestire il modello northwindEntities e di permettere l'accesso completo a tutte le entità.

public class Northwind : DataService
{
  // This method is called only once to initialize service-wide policies.
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
  }
}

A questo punto si debbono inserire nel web.config le stringhe di connessione relative al modello di EF ed una volta che il servizio è configurato si può navigare con un browser all'indirizzo:

http://localhost:1353/northwind.svc/Customer

Il risultato è un feed contenente tutti gli oggetti customers presenti nel database, se invece si volesse recuperare solamente uno specifico cliente è possibile utilizzare questa richiesta

http://localhost:1353/northwind.svc/Customer('ALFKI')

Naturalmente è possibile anche effettuare query, come ad esempio visualizzare solamente i clienti che vivono a Berlino, ecco un esempio:

http://localhost:1353/northwind.svc/Customers?$filter=City%20eq%20'Berlin'

In questo modo con EF e due righe di codice su un servizio WCF abbiamo creato un Data Access Layer accessibile da webservice.

Ti consigliamo anche