c# - Can you get the DbContext from a DbSet? -
in application necessary save 10,000 or more rows database in 1 operation. i've found iterating , adding each item 1 @ time can take upwards of half hour.
however, if disable autodetectchangesenabled takes ~ 5 seconds (which want)
i'm trying make extension method called "addrange" dbset disable autodetectchangesenabled , re-enable upon completion.
public static void addrange<tentity>(this dbset<tentity> set, dbcontext con, ienumerable<tentity> items) tentity : class { // disable auto detect changes speed var detectchanges = con.configuration.autodetectchangesenabled; try { con.configuration.autodetectchangesenabled = false; foreach (var item in items) { set.add(item); } } { con.configuration.autodetectchangesenabled = detectchanges; } }
so, question is: there way dbcontext dbset? don't making parameter - feels should unnecessary.
yes, you can dbcontext
dbset<tentity>
, solution reflection heavy. have provided example of how below.
i tested following code , able retrieve dbcontext
instance dbset
generated. please note that, although answer question, there better solution problem.
public static class hackydbsetgetcontexttrick { public static dbcontext getcontext<tentity>(this dbset<tentity> dbset) tentity: class { object internalset = dbset .gettype() .getfield("_internalset",bindingflags.nonpublic|bindingflags.instance) .getvalue(dbset); object internalcontext = internalset .gettype() .basetype .getfield("_internalcontext",bindingflags.nonpublic|bindingflags.instance) .getvalue(internalset); return (dbcontext)internalcontext .gettype() .getproperty("owner",bindingflags.instance|bindingflags.public) .getvalue(internalcontext,null); } }
example usage:
using(var originalcontextreference = new mycontext()) { dbset<myobject> set = originalcontextreference.set<myobject>(); dbcontext retrievedcontextreference = set.getcontext(); debug.assert(referenceequals(retrievedcontextreference,originalcontextreference)); }
explanation:
according reflector, dbset<tentity>
has private field _internalset
of type internalset<tentity>
. type internal entityframework dll. inherits internalquery<telement>
(where tentity : telement
). internalquery<telement>
internal entityframework dll. has private field _internalcontext
of type internalcontext
. internalcontext
internal entityframework. however, internalcontext
exposes public dbcontext
property called owner
. so, if have dbset<tentity>
, can reference dbcontext
owner, accessing each of properties reflectively , casting final result dbcontext
.
update @loneypixel
in ef7 there private field _context directly in class implements dbset. it's not hard expose field publicly
Comments
Post a Comment