2010-09-15 6 views
8

Sto codificando con i blocchi 'using' ma mi chiedo se posso restituire un IQueryable dal seguente senza che l'oggetto venga eliminato prima dell'accesso.Come posso restituire una query IQueryable da Linq a SQL quando dbContext è con un blocco 'using'?

public IQueryable<Contact> GetContacts(string clientID) 
{ 
    using (dbDataContext db = new dbDataContext()) 
    { 
     var contacts = from _contacts in db.Contacts 
         where _contacts.ClientID == clientID 
         orderby _contacts.LastName ascending 
         select _contacts; 

     return contacts; 
    } 
} 

Do ho semplicemente rimuovere il blocco 'con' e lasciare .Net gestire gli oggetti, o posso avere LINQ per eseguire la query iniziale e restituisce l'oggetto popolato.

+0

nota che non è veramente necessario disporre esplicitamente il datacontext. buona domanda comunque comunque. – fearofawhackplanet

+0

@fearofawhackplanet - ehm, sì, lo è. Qualsiasi oggetto usa e getta dovrebbe essere assunto per ** richiedere ** smaltimento, e deve essere gestito in modo appropriato, IMO. Può contenere una connessione aperta, ad esempio ... –

+0

@Marc: Sto solo andando su quello che ho letto su diversi blog, e anche praticamente tutti gli esempi di ScottGu e del team di Linq. La posizione ufficiale Microsoft, per quanto posso raccogliere, è che puoi disporre se ti fa sentire meglio, ma in realtà non è necessario. Vedi http://leedumond.com/blog/about-disposing-the-datacontext/ come esempio per alcune discussioni sullo smaltimento e il problema dell'esecuzione posticipata descritto in questa domanda. – fearofawhackplanet

risposta

6

Se non si prevede di comporre ulteriormente i dati (al db-server), quindi:

return contacts.ToList().AsQueryable(); 

anche se in quel caso avrei preferito tornare IEnumerable<Contact> o IList<Contact> per rendere la non natura componibile ovvia. Con l'approccio AsQueryable, sarà ancora essere componibile, ma verrà composto tramite LINQ-to-Objects (quindi dopo ha recuperato i record dal database).

Se fai aspettano per comporre ulteriormente, allora si dovrebbe passare il contesto dati (o, se possibile, un monte IQueryable<something>) in il metodo, e lasciare gestire il chiamante il corso della vita:

public IQueryable<Contact> GetContacts(dbDataContext db, string clientID) 
{ 
    return from _contacts in db.Contacts 
      where _contacts.ClientID == clientID 
      orderby _contacts.LastName ascending 
      select _contacts; 
} 
+0

@IckleMonkey - è il tipo * concreto * che conta di più, ma un ovvio vantaggio di 'IList ' è che esporrà '.Count' ecc. (E un indicizzatore), rendendo l'accesso più conveniente.Ma indipendentemente da 'IList ' vs 'IEnumerable ', è ancora * è * un 'Elenco ', quindi l'utilizzo della memoria è indipendente. O per una risposta più concisa: usa 'IList ' –

-1

si potrebbe fare qualcosa di simile

public IQueryable<Contact> GetContacts(string clientID) 
{ 
    IQueryable contacts; 
    using (dbDataContext db = new dbDataContext()) 
    { 
     contacts = from _contacts in db.Contacts 
         where _contacts.ClientID == clientID 
         orderby _contacts.LastName ascending 
         select _contacts; 


    } 

    return contacts; 
} 
+2

Ciò non aiuta - l'esecuzione posticipata delle query LINQ significa che il contesto db è ancora disposto molto prima che 'GetEnumerator()' venga chiamato nella query sottostante. Quindi nessun problema. –

0

si può fare il contesto oggetto un'istanza membro della vostra classe? Se è possibile, rinvierai la chiamata per eseguire la query finché non tocchi effettivamente l'enumeratore sottostante all'istanza IQueryable che stai restituendo. Dipende da cosa vuoi fare. Devi restituire IQueryable da questo metodo o puoi accontentarti di IEnumerable?

+0

Penso che andrò con l'IEnumerable, se utilizzo il metodo di istanza del membro, quindi potrei incappare nello stesso problema se la mia classe è usata come un blocco 'using' e voglio accedere ai dati restituiti al di fuori di questo. Grazie per il suggerimento. – polom1nt

0

L'istanza dell'oggetto contatto nel set di risultati IQueryable manterrà il riferimento del datacontext utilizzato all'interno del blocco using e funzionerà nel codice client come previsto. Sarai in grado di eseguire operazioni SQL differite sull'istanza IQueryable risultante e fare normalmente altre operazioni IQueryable.

+1

Quando provo, ottengo "Accesso DataContext dopo Dispose". – polom1nt

Problemi correlati