c# - "The operation cannot be completed because the DbContext has been disposed" exception with lazy load disabled -
given:
public actionresult list() { using (var unitofwork = new unitofwork()) { var result = unitofwork.repository.find<entityaddress>(a => a.postalcode == "80001"); //return view(result.tolist());//no exception raised tolist() return view(result);//exception raised in view during iteration } }
unitofwork
disposable , handles disposal of dbcontext. disables lazy loading in constructor:
public unitofwork() { _dbcontext.configuration.lazyloadingenabled = false; repository = new genericrepository<myentities>(_dbcontext); } public void dispose() { repository.dispose(); }
and find<entityaddress>()
implementation works out to:
_dbcontext.set<entityaddress>().where(predicate)
predicate parameter of type expression<func<entityaddress, bool>>
why disposal exception after disabled lazy loading?
lazy , eager loading have when entities related query (e.g. navigation properties , collections) loaded, not when contents of query loaded.
the iquerable<entityaddress>
returned repository—whether or not have lazy loading enabled—will not run query on server until it's enumerated (whether that's getting enumerator in foreach
loop, calling enumerable.tolist<tsource>
on it, or passing call controller.view
downstream rendering).
the reason exception in case because controller.view
not render view (and therefore not enumerate query). construct instance of viewresult
holds onto model parameter (your query object) until mvc render view later on, after you've disposed context.
if want pass query results view, have 2 options:
- extend life of database context lifetime of controller
- call
enumerable.tolist<entityaddress>
oniquerable<entityaddress>
before database context disposed, , use resultinglist<entityaddress>
instead ofiquerable<entityaddress>
.
Comments
Post a Comment