Using mvc-mini-profiler database profiling with Entity Framework Code First -
i'm using mvc-mini-profiler in project built asp.net mvc 3 , entity framework code-first.
everything works great until attempt add database profiling wrapping connection in profileddbconnection
described in documentation. since i'm using dbcontext, way attempting provide connection through constructor using static factory method:
public class mydbcontext : dbcontext { public mydbcontext() : base(getprofilerconnection(), true) { } private static dbconnection getprofilerconnection() { // code below errors //return profileddbconnection.get(new sqlconnection(configurationmanager.connectionstrings["myconnectionname"].connectionstring)); // code below works fine... return new sqlconnection(configurationmanager.connectionstrings["myconnectionname"].connectionstring); } //... }
when using profileddbconnection
, following error:
providerincompatibleexception: provider did not return providermanifesttoken string.
stack trace:
[argumentexception: connection not of type 'system.data.sqlclient.sqlconnection'.] system.data.sqlclient.sqlproviderutilities.getrequiredsqlconnection(dbconnection connection) +10486148 system.data.sqlclient.sqlproviderservices.getdbprovidermanifesttoken(dbconnection connection) +77 system.data.common.dbproviderservices.getprovidermanifesttoken(dbconnection connection) +44 [providerincompatibleexception: provider did not return providermanifesttoken string.] system.data.common.dbproviderservices.getprovidermanifesttoken(dbconnection connection) +11092901 system.data.common.dbproviderservices.getprovidermanifesttoken(dbconnection connection) +11092745 system.data.entity.dbmodelbuilder.build(dbconnection providerconnection) +221 system.data.entity.internal.lazyinternalcontext.createmodel(lazyinternalcontext internalcontext) +61 system.data.entity.internal.retrylazy`2.getvalue(tinput input) +1203482 system.data.entity.internal.lazyinternalcontext.initializecontext() +492 system.data.entity.internal.internalcontext.getentitysetandbasetypefortype(type entitytype) +26 system.data.entity.internal.linq.internalset`1.initialize() +89 system.data.entity.internal.linq.internalset`1.get_internalcontext() +21 system.data.entity.infrastructure.dbquery`1.system.linq.iqueryable.get_provider() +44 system.linq.queryable.where(iqueryable`1 source, expression`1 predicate) +135
i have stepped through , type returned profileddbconnection.get
of type profileddbconnection
(even if current miniprofiler null).
the miniprofiler.start()
method called within global application_beginrequest()
method before dbcontext
instantiated. calling start method every request regardless calling stop if user not in correct role:
protected void application_beginrequest() { // don't know user @ stage need start miniprofiler.start(); } protected void application_authorizerequest(object sender, eventargs e) { // stop profiler if user not developer if (!authorisationhelper.isdeveloper()) { mvcminiprofiler.miniprofiler.stop(discardresults: true); } } protected void application_endrequest() { miniprofiler.stop(); }
i'm not sure if affects things i'm using structuremap ioc dbcontext
using following initialiser:
for<mydbcontext>().singleton().hybridhttporthreadlocalscoped();
i understand there similar question on here explanation of what's happening user, doesn't seem solve problem.
edit:
for clarity. attempting pass connection profileddbconnection
in order profile generated sql entity framework code first.
the entity framework expecting connection type sqlconnection
of course isn't.
here example of connection string (notice providername)
<add name="mydbcontext" connectionstring="server=.\sqlexpress; database=mydatabase;trusted_connection=true;multipleactiveresultsets=true" providername="system.data.sqlclient" />
i attempted create own version of profileddbconnection
inheriting sqlconnection
sealed class.
if there way of telling entity framework custom connection type perhaps work. tried setting providername
in connection string mvcminiprofiler.data.profileddbconnection
didn't work.
so. perhaps evolution of question be: how can pass custom connection type entity framework code first?
this supported, check out latest source or grab package nuget.
you need miniprofiler.ef package if using nuget. (1.9.1 , up)
supporting involved large set of modifications underlying proxy object support acting ef code first proxies.
to add support:
during application_start
run:
miniprofileref.initialize();
note: ef code first store table metadata in table called: edmmetadata
. metadata uses provider part of entity key. if initialized provider non-profiled provider, have re-build metadata. deleting rows edmmetadata
may trick, alternatively smarter providers able handle transparently.
Comments
Post a Comment