Utilizzare le stored procedure con Entity Framework

Stefano Mostarda

di Stefano Mostarda, in LINQ, 10 febbraio 2009

3 pagine in totale: <<Indietro 1 2 [3]

Recuperare valori semplici o liste di valori semplici

Alcune stored procedure ritornano un dato secco oppure una lista di dati semplici. Ad esempio, potremmo avere una stored procedure che somma tutti gli ordini e torna il totale del fatturato. In un altro caso, potremmo avere una stored procedure che torna una lista di id.

In questi casi il designer ci viene in aiuto solo per metà in quanto genera il mapping, ma non il codice necessario ad eseguire la funzione. A differenza di come si è visto per il mapping di una entità, quando si deve scegliere verso cosa mappare la stored procedure, si deve scegliere la seconda opzione, Scalars, e specificare il tipo di ritorno come nella seguente figura.

Importare una funzione che mappa su valori semplici

Il codice per eseguire la funzione non viene generato perché il metodo per eseguire una funzione è ExecuteFunction che si trova nella classe ObjectContext ed accetta in input un parametro generico che corrisponde al tipo di ritorno della funzione. Questo parametro generico deve implementare l'interfaccia IEntityWithChangeTracker che tutte le classi generate dal designer implementano indirettamente. Poiché le altre classi del .NET Framework non implementano questa interfaccia, il metodo ExecuteFunction è inusabile. L'unico metodo per invocare queste stored procedure è ricorrere all'Entity Client.

using (var conn = new EntityConnection("name=SPEFEntities")) { 
  using (var comm = conn.CreateCommand()) { 
    comm.CommandType = CommandType.StoredProcedure; 
    comm.CommandText = "SPEFEntities.GetOrdersAmount"; 
    conn.Open(); 
    var x = Convert.ToDecimal(comm.ExecuteScalar()); 
  } 
}

In questo caso abbiamo ritrovato un valore semplice utilizzando il metodo ExecuteScalar. Nel caso di una lista di dati semplici, basta ricorrere al metodo ExecureReader e scorrere il datareader.

Modificare i dati

La modifica dei dati tramite stored procedure ha meno complicazioni rispetto alla lettura dei dati. Inoltre, il designer ha una copertura completa di questa feature e quindi non dobbiamo preoccuparci di modificare il mapping a mano e nemmeno di dover generare del codice. Infine, l'utilizzo delle stored procedure è completamente trasparente al codice quindi non dobbiamo modificare il nostro approccio.

La prima regola per aggiornare i dati di una classe è "tutto o niente". La persistenza di una classe prevede l'inserimento, la modifica e la cancellazione dei dati. Se si vogliono utilizzare stored procedure, bisogna utilizzarle per tutte le funzioni di persisteza di una classe. Questo significa che non si può usare una stored procedure per l'inserimento e lasciare che Entity Framework generi il codice SQL per la modifica e la cancellazione altrimenti viene generata un'eccezione a run time.

Supponiamo di gestire l'inserimento di un utente. Questo caso ha un cavillo. Poiché la tabella ha una primary key autogenerata, dobbiamo fare in modo che dopo l'inserimento questa sia restituita al framework che poi la utilizzerà per inserire i metodi di pagamento. Per fare questo la stored procedure deve restituire un resultset che in una colonna specifica l'id.

CREATE Procedure [dbo].[InsertUser] 
@customer varchar(50) 
as 
insert into [user] values(@customer) 
 
select SCOPE_IDENTITY() as id

Nel designer, una volta importata la stored procedure, bisogna cliccare col tasto destro sull'entità da persistere e selezionare la voce "Stored Procedure Mapping". Nella finestra Mapping Details, basta mappare la classe con le stored procedure come mostrato nella seguente figura.

mappare stored procedure per persistere i dati

Nel nodo Parameters si specifica il mapping tra le proprietà della classe ed i parametri della stored procedure. Nel nodo Result Column Bindings della stored procedure che inserisce i dati si specifica che la colonna Id del resultset di output della stored procedure viene usata per valorizzare la proprietà OrderId della classe.

Nella fase di update si può gestire anche la concorrenza ottimistica. Poiché l'ObjectContext mantiene sia i valori originali che quelli correnti di ogni entità, possiamo creare una stored procedure che accetta entrambi per tutti i campi e gestire in questo modo la concorrenza così da non aggiornare dati obsoleti. Nei parametri della stored procedure di update c'è il check "Use Original Value" che specifica se il parametro verrà popolato con il valore originale (checkbox valorizzato) o con quello originale (checkbox vuoto).

Modificare i dati in presenza di ereditarietà

Precedentemente abbiamo visto che la regola principale quando si tratta di aggiornare i dati utilizzando stored procedure è che tutte le operazioni devono essere svolte utilizzando una stored procedure. Quando si deve aggiornare un'entità che fa parte di una gerarchia, c'è una seconda regola da tenere in mente: tutte le classi concrete, ovvero non astratte, che fanno parte della gerarchia devono essere persistite utilizzando stored procedure. Questo significa che se si ha una gerarchia composta da diverse classi, bisogna creare tre stored procedure per ognuna di esse rischiando di far crescere in maniera eccessiva il loro numero. Tuttavia, in molti contesti la necessità di utilizzare stored procedure è molto sentita è quindi l'aumento del numero di queste non rappresenta un problema.

Conclusioni

In questo articolo abbiamo scoperto come l'utilizzo delle stored procedure con entity framework sia abbastanza semplice. Purtroppo esistono ancora alcune casistiche che non sono completamente gestite come la possibilità di effettuare eager loading di dati o di gestire resultset multipli. Tuttavia, allo stato attuale siamo già ad un buon punto e nelle prossime versioni c'è da aspettarsi che gran parte delle lacune attuali vengano coperte.

3 pagine in totale: <<Indietro 1 2 [3]

Contenuti dell'articolo

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

TUTORIALS
TOP TEN ARTICOLI
ARTICOLI VIA E-EMAIL

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

MEDIA
IN EVIDENZA
MISC