asp.net mvc - How to change database name in dbcontext connection string at runtime -
my asp.net mvc application setup follows. there 4 projects in solution.
- ge.web
- ge.bll
- ge.core
- ge.entities
controller in ge.web initializes repository object present in ge.core
public class mapscontroller : controller { private assessmentrepository repassessments = new assessmentrepository("name=gecontext", schoolcode); public actionresult displaysearchresults() { ..... } }
assessments repository
public class assessmentrepository : repository<assessment>, iassessmentrepository { public assessmentrepository(string connstring, string schoolcode) :base(connstring, schoolcode) { } }
repository
public class repository<tentity> : irepository<tentity> tentity:class { protected readonly gecontext context; public repository(string connstring, string schoolcode) { context = new gecontext(connstring); } }
gecontext
public class gecontext : dbcontext { public gecontext(string connstring):base(connstring) { this.configuration.lazyloadingenabled = false; database.setinitializer(new mysqlinitializer()); } }
dbcontext
public class dbcontext : idisposable, iobjectcontextadapter { public dbcontext(string nameorconnectionstring); }
web.config
<add name="gecontext" connectionstring="server=localhost;port=4040;uid=root;pwd=xxx;database=ge" providername="mysql.data.mysqlclient" />
now want replace "database=ge" present in web.config database=ge_[schoolcode]. @ runtime how can go it?
update solution did not work. stating problem once again.
web.config
i have changed config file following (previously gecontext connection string)
<connectionstrings> <add name="gecontext_sc001" connectionstring="server=localhost;port=4040;uid=root;pwd=blabla;database=db_sc001" providername="mysql.data.mysqlclient" /> <add name="gecontext_sc002" connectionstring="server=localhost;port=4040;uid=root;pwd=blabla;database=db" providername="mysql.data.mysqlclient" />
<appsettings> <add key="schoolcodes" value="sc001,sc002"/>
these allowed schoolcodes
now when user enters schoolcode @ login screen, validated against codes present in schoolcodes key. , if yes, should try connect connectionstring particular connection. when code comes
usermanager.findasync
in login function of accountcontroller, crashes trying find gecontext. set? , how can change it?
i have changed repository calling in controller follows
private static string schoolcode = (string)system.web.httpcontext.current.session["schoolcode"]; private assessmentrepository repassessments = new assessmentrepository("name=gecontext_" + schoolcode);
update-2 following present in ge.web
identityconfig.cs
public class applicationusermanager : usermanager<applicationuser, int> { public applicationusermanager(iuserstore<applicationuser, int> store) : base(store) { } public static applicationusermanager create(identityfactoryoptions<applicationusermanager> options, iowincontext context) { var manager = new applicationusermanager(new userstore<applicationuser, role, int, userlogin, userrole, userclaim>(context.get<applicationdbcontext>())); ........... }
the following present in ge.core
applicationdbcontext
public class applicationdbcontext : identitydbcontext<applicationuser, role, int, userlogin, userrole, userclaim> { public applicationdbcontext(string connstring) : base(connstring) { database.setinitializer(new mysqlinitializer()); } public static applicationdbcontext create() { return new applicationdbcontext("name=gecontext_"); } }
how can pass schoolcode ge.web ge.core (answer should straight forward cant head around it)
update-3
as told itikhomi , taking this post have changed code follows
in applicationdbcontext class added following
public static applicationdbcontext create(string sccode){ return new applicationdbcontext("name=gecontext_" + sccode); }
in accountcontroller login
var appdbcontext = applicationdbcontext.create(model.schoolcode);
request.getowincontext().set<applicationdbcontext>(appdbcontext);
it still not hit correct database
you have 2 ways
1)
using system.data.sqlclient; public class repository<tentity> : irepository<tentity> tentity:class { protected readonly gecontext context; public repository(string connstring, string schoolcode) { context = new gecontext(connstring); var connection = new sqlconnectionstringbuilder(context.database.connection.connectionstring); connection.initialcatalog = "your_prefix_fromsomewhere"+schoolcode; context.database.connection.connectionstring = connection.connectionstring; } }
2) if wants switch connection when opened before use changedatabase:
//open connection if close context.database.connection.changedatabase("database-name");
note: if use changedatabase connection should opened
for update3:
you need somethink this:
public class applicationdbcontext : identitydbcontext<applicationuser> { public applicationdbcontext() : base("defaultconnection", throwifv1schema: false) { } public applicationdbcontext(string schoolcode) : base(schoolcode) { var connection = new sqlconnectionstringbuilder(this.database.connection.connectionstring); connection.initialcatalog = "your_prefix_fromsomewhere" + schoolcode; this.database.connection.connectionstring = connection.connectionstring; } public static applicationdbcontext create() { return new applicationdbcontext(); } }
in account controller:
public applicationsigninmanager signinmanager { { if (_signinmanager == null) { var code = httpcontext.request.form.get("schoolcode");//get form\querystring\session whatever wants if (code != null) { httpcontext.getowincontext().set<applicationsigninmanager>(new applicationsigninmanager(_usermanager, httpcontext.getowincontext().authentication)); } _signinmanager = httpcontext.getowincontext().get<applicationsigninmanager>(); } return _signinmanager; } private set { _signinmanager = value; } } public applicationusermanager usermanager { { if (_usermanager == null) { var code = httpcontext.request.form.get("schoolcode");//get form\querystring\session whatever wants if (code != null) { var appdbcontext = new applicationdbcontext(code); httpcontext.getowincontext().set<applicationdbcontext>(appdbcontext); httpcontext.getowincontext().set<applicationusermanager>(new applicationusermanager(new userstore<applicationuser>(appdbcontext))); //or use specified create method } _usermanager = httpcontext.getowincontext().getusermanager<applicationusermanager>(); } return _usermanager; } private set { _usermanager = value; } }
your problem in store of usermanager created before change owin context, in case better use di here
Comments
Post a Comment