Domanda

Sono un principiante assoluto di Entity Framework e ASP.Net MVC, avendo imparato principalmente dai tutorial, senza avere una profonda comprensione di entrambi. (Ho esperienza su .Net 2.0, ADO.Net e WebForms)

Il mio attuale dubbio deriva dal modo in cui installo i miei oggetti Entity.

Fondamentalmente lo sto facendo nei miei controller:

public class PostsController : Controller {

    private NorthWindEntities db = new NorthWindEntities();

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

Lo sto facendo in questo modo perché l'ho trovato in qualche blog MSDN che mi è sembrato abbastanza autorevole da supporre che fosse un modo corretto.
Tuttavia, mi sento piuttosto non facile a riguardo. Anche se mi fa risparmiare un sacco di codice, sono abituato a fare:

using (NorthWindEntities db = new NorthWindEntities() {
}

In ogni singolo metodo che necessita di una connessione, e se quel metodo chiama altri che ne avranno bisogno, passerà loro db come parametro. È così che 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 suo metodo Dispose (), e non lo sono.

Cosa ne pensi di questo?
È corretto istanziare l'oggetto Entità mentre sto facendo? Dovrebbe occuparsi delle sue connessioni aprendole e chiudendole per ogni query?
O dovrei eliminarlo esplicitamente con una clausola using ()?

Grazie!

È stato utile?

Soluzione

Il controller stesso implementa IDisposable. Quindi puoi sovrascrivere Dispose e smaltire qualsiasi cosa (come un contesto di oggetto) che inizializzi 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 del rendering della vista. Pertanto, se si crea ObjectContext in un'istruzione using all'interno dell'azione, ObjectContext sarà stato eliminato prima del rendering della vista. Quindi è meglio aver 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 eliminato il contesto prima del rendering della vista, causando un'eccezione quando la vista tenta di enumerare IQueryable.

Al contrario, se si inizializza l'ObjectContext quando viene inizializzato il Controller (o si scrive un codice di inizializzazione pigro che lo fa inizializzare quando viene eseguita l'azione) e si elimina l'ObjectContext in Controller.Dispose, il contesto sarà comunque intorno quando viene visualizzata la vista. In questo caso, è sicuro passare un IQueryable alla vista. Il controller verrà eliminato poco dopo il rendering della vista.

Infine, sarei remissivo se non avessi fatto notare che probabilmente è una cattiva idea che il tuo Controller sia a conoscenza dell'Entity Framework. Cerca di utilizzare un assembly separato per il tuo modello e il modello di repository affinché il controller parli con il modello. Una ricerca su Google si aprirà un po 'su questo.

Altri suggerimenti

Stai facendo un buon punto qui. Per quanto tempo deve rimanere ObjectContext? Tutti i libri di modelli e pratiche (come Microsoft-NET-Architecting-Applications ) ti dice che un DataContext non deve vivere a lungo, né deve essere memorizzato nella cache.

Mi stavo solo chiedendo perché non avere, nel tuo caso, una classe ControllerBase (non sono a conoscenza dell'implementazione MVC, quindi abbiate pazienza con me) in cui ObjectContext viene avviato una volta per tutti i controller. Pensa in particolare al Identity Map Pattern , che è già implementato da Entity Framework. Anche se devi chiamare un altro controller come PostController, funzionerebbe comunque con lo stesso contesto e migliorerebbe anche le prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top