c# - Disposing DataContext/ObjectContext without breaking deferred execution code -


c# 6.0 in nutshell joseph albahari , ben albahari (o’reilly).

copyright 2016 joseph albahari , ben albahari, 978-1-491-92706-9.

brings, @ page 376, discussion on disposing datacontext/objectcontext instances.

disposing datacontext/objectcontext

although datacontext/objectcontext implement idisposable, can (in general) away without disposing instances. disposing forces context’s connection dispose—but unnecessary because l2s , ef close connections automatically whenever finish retrieving results query. disposing context can problematic because of lazy evaluation. consider following:

iqueryable<customer> getcustomers (string prefix) {    using (var dc = new nutshellcontext ("connection string"))    return dc.gettable<customer>()    .where (c => c.name.startswith (prefix)); }  ... foreach (customer c in getcustomers ("a")) console.writeline (c.name); 

this fail because query evaluated when enumerate it—which after disposing datacontext.

there caveats, though, on not disposing contexts.

(and goes on list them...)

at end, avoid exception described, states:

if want explicitly dispose contexts, must pass datacontext/objectcontext instance methods such getcustomers avoid problem described.

the question:

i not author meant. (no example followed).

i mean, author's says can have method still return iqueryable<customer>, dispose of datacontext parameter , keep deferred execution altogether ?

how achieved ? can see happening if giving lazy loading.

there conflict between concept of lazy loading , repository pattern. repository pattern, datacontext/objectcontext designed for, separate code accesses database code consumes business objects.

the fundamental problem lazy loading properties business objects being returned data layer depend on , utilize technology specific data retrieval when may not expected.

some examples:

the underlying data retrieval mechanism has been disposed of when trying access lazy loading properties later. author trying explain.

customer mycustomer; using (var datasource = getrepository()) {    mycustomer = datasource.retrieve("john"); }  // throws exception since connection // database has been closed var orders = mycustomer.orders;  

you may have code somewhere in ui attempts read property, triggers database call , slows down ui. sqlexception may occur retrieving properties in unexpected places, leading either unreliability or tight coupling between data store , consumer code.

// business layer customer mycustomer = myrepository.getcustomer("john");  ... // ui component trying show customer's orders var orders = mycustomer.orders;  // throw kind of data access exception, such sqlexception // e.g. wifi not working anymore, have build error // handling here, though it's not obvious // accessing orders property 

note in humble opinion, worse having explicit coupling between data , logic layers, since coupling there, hidden view.


Comments