2013-04-17 10 views
7

Qual è la Best Practice nel dichiarare Entity Framework ContestiDichiarare Entity Framework Contesti con l'utilizzo di

function() 
{ 
    DBContext context = new DBContext(); 

    //Entity code 

    return ; 
} 

o

function() 
{ 
    using(DBContext context = new DBContext()) 
    { 
     //Entity code 
    } 
} 

Abbiamo bisogno di usare l'utilizzo in EntityFramework? Se sì la mia seconda domanda

In DataAccess layer sto eseguendo EF e memorizzare il risultato in IEnumerable all'interno utilizzando

MY DL

function() 
{ 
    IEnumerable something = null; 
    using(DBContext context = new DBContext()) 
    { 
     IEnumerable something = .... 
    } 
    return something; 
} 

controller

function() 
{ 
    List some = something.ToList(); 
} 

E nel mio controller am ottenendo questo come una lista come ho bisogno di fare un po 'Trova operazione sto ottenendo

"The operation cannot be completed because the DbContext has been disposed Entity Framework" 

Sì posso restituire un elenco da DL e funziona benissimo

Come posso gestire questo se io uso utilizzando con IEnumerable?

+1

penso che questo SO collegamento è esattamente ciò che hai chiesto: http://stackoverflow.com/questions/824330/should-entity-framework-context-be-put-into-using-statement?rq = 1 –

+0

sì nel caso si prega di controllare la mia seconda domanda – user2067567

+0

possibile duplicato di [Uso di Statement and Entity Framework] (http://stackoverflow.com/questions/13826536/using-statement-and-entity-framework) – Habib

risposta

7

È possibile evitare il comportamento EF lazy-carico chiamando .ToList() sul IEnumerable prima che il contesto è disposto (cioè all'interno del tuo using blocco)

+0

Grazie a @paul . come posso dire alla mia seconda domanda. è un modo sbagliato? – user2067567

+0

Sì, uso ancora usando come disse Paul. +1 dato. Si ottiene comunque un problema simile se il tuo modello ha oggetti grandchild. Non ho ancora passato il tempo a risolverlo. – James

+1

@James Penso che puoi ottenere i tuoi figli/nipoti usando '.Include()' nell'istruzione Linq originale – paul

3

La tua richiesta verrà eseguita verso l'origine dati non appena si chiami .ToList() metodo.

Ecco perché non è possibile eseguire .ToList() nel Controller come contesto che è stato disposto alla fine del blocco using.

nel metodo DL, basta fare qualcosa di simile:

IEnumerable<Something> function() 
{ 
    using(DBContext context = new DBContext()) 
    { 
     return something.ToList(); 
    } 
} 

e il Controller si otterrà un IEnumerable di qualcosa:

var mySomethingIEnumerable = DL.Function(); 

Speranza che aiuta!

6

Sì, un utilizzo è la procedura migliore perché ripulisce il contesto. Il Using statement è una scorciatoia per:

try { 
    // Execute your code inside the using statement 
} 
finally { 
    // Cleanup the context no matter what by calling .Dispose() 
} 

Tenete a mente, il contesto probabili rendimenti IEnumerables e dal EF supporta il caricamento pigro questi oggetti non verrà popolata fino a quando non li recupero su una collezione concreta (cioè yourResult.ToList.()).

esito negativo comune si verifica in questo scenario:

public IEnumerable<Employee> GetEmployeesInAccounting() 
{ 
    using(var myContext = new MyDbContext()) 
    { 
     return myContext.Employees.Where(emp => emp.Department == 'Accounting'); 
    } 
} 

// Code that fails, Assuming Manager is a lazy loaded entity, this results in an exception but it compiles no problem 
var acctEmps = GetEmployeesInAccounting(); 
var something = acctEmps.First().Department.Manager.Department; 

È possibile evitare questo utilizzando il (metodo di estensione LINQ) .Include(emp => emp.Manager) e vincolante il risultato utilizzando .ToList();