2009-09-09 13 views
17

Sono un newbie totale a Entity Framework e ASP.Net MVC, avendo imparato per lo più da tutorial, senza avere una profonda conoscenza di entrambi. (Io ho esperienza su .Net 2.0, ADO.Net e WebForms)Entity Framework - Come dovrei esempio la mia oggetto "Entità"

Il mio dubbio attuale deriva dal modo in cui sto instancing miei oggetti entità.

Fondamentalmente io sto facendo questo nei miei controllori:

public class PostsController : Controller { 

    private NorthWindEntities db = new NorthWindEntities(); 

    public ActionResult Index() { 
      // Use the db object here, never explicitly Close/Dispose it 
    } 
} 

che sto facendo in questo modo perché ho trovato in qualche blog MSDN che sembrava abbastanza autorevole per me che ho assunto questo era un modo corretto .
Tuttavia, mi sento piuttosto inopportuno in merito. Anche se mi fa risparmiare un sacco di codice, io sono abituato a fare:

using (NorthWindEntities db = new NorthWindEntities() { 
} 

in ogni singolo metodo che ha bisogno di una connessione, e se questo metodo chiama altri che avrò bisogno, che passerà db come un parametro per loro. Ecco come ho fatto tutto con i miei oggetti di connessione prima che esistesse Linq-to-SQL.

L'altra cosa che mi mette a disagio è che NorthWindEntities implementa IDisposable, che per convenzione significa che dovrei chiamare il metodo Dispose(), e non lo sono.

Cosa ne pensi di questo?
È corretto istanziare l'oggetto Entità come sto facendo? Dovrebbe occuparsi delle sue connessioni aprendole e chiudendole per ogni domanda?
Oppure devo smaltirlo in modo esplicito con una clausola using()?

Grazie!

risposta

21

Il controllore stesso implementa IDisposable. In questo modo è possibile ignorare Dispose e smaltire qualsiasi cosa (come un contesto di oggetto) che si inizializza quando il controller viene istanziato.

Il controller dura solo una singola richiesta. Quindi avere un utilizzo all'interno di un'azione e avere un contesto oggetto per l'intero controller è esattamente lo stesso numero di contesti: 1.

La grande differenza tra questi due metodi è che l'azione sarà completata prima che la vista sia resa. Quindi, se crei il tuo ObjectContext in un'istruzione using all'interno dell'azione, ObjectContext sarà stato eliminato prima della visualizzazione del rendering. Quindi è meglio che tu abbia letto qualsiasi cosa dal contesto di cui hai bisogno prima che l'azione venga completata. Se il modello che passi alla vista è un elenco pigro come un IQueryable, avrai disposto il contesto prima del rendering della vista, causando un'eccezione quando la vista tenta di enumerare l'IQueryable.

Al contrario, se si inizializza l'ObjectContext quando il Controller viene inizializzato (o scrive il codice di inizializzazione pigro provocando l'inizializzazione quando viene eseguita l'azione) e si dispone dell'oggetto ObjectContext nel Controller.Dispose, il contesto sarà comunque essere in giro quando la vista è resa. In questo caso, è sicuro passare un IQueryable alla vista. Il controller verrà eliminato poco dopo il rendering della vista.

Infine, sarei negligente se non sottolineare che è probabilmente una cattiva idea di avere il Controller essere a conoscenza di Entity Framework a tutti. Cerca di utilizzare un assembly separato per il tuo modello e il pattern di repository per far dialogare il controller con il modello. Una ricerca su Google comparirà un po 'su questo.

+0

Ok, questo ha senso. Ora, la domanda è ... Sto facendo le cose in modo errato? Ho davvero bisogno di disporre dell'oggetto Entities? Cosa succede se non lo faccio? Devo "perdere" le connessioni a SQL Server? –

+1

ObjectContext.Dispose non fa molto (vedi Reflector). Ma è ragionevole presumere che potrebbe cambiare e tu * dovresti * eliminarlo. –

3

Stai facendo un buon punto qui.Quanto deve durare l'ObjectContext? Tutti i libri di modelli e pratiche (come Dino Esposito Microsoft-NET-Architecting-Applications) indicano che un DataContext non deve vivere a lungo, né dovrebbe essere memorizzato nella cache.

Mi stavo chiedendo perché non ho, nel tuo caso, una classe ControllerBase (non sono a conoscenza dell'implementazione di MVC, quindi tieni con me) dove l'ObjectContext viene avviato una volta per tutti i controller. Pensa in particolare allo Identity Map Pattern, che è già implementato da Entity Framework. Anche se è necessario chiamare un altro controller come PostsController, funzionerà comunque con lo stesso contesto e migliorerà anche le prestazioni.

Problemi correlati