The user connect using the regular ApplicationDbContext and now I want to set my other DContext => ApplicationDataContextto another Database based on what is the user role.
The User1 may have to use DefaultConnectionString1 while my User2 may have to use DefaultConnectionString2 and User3 may have to use DefaultConnectionString1 as well.
So, I need to changethe Connection String from my ApplicationDataContext (not the ApplicationDbContext) which inherit from DbContext. Depending on the user who is authenticated.
Reason is I want for example that User1 point to Database MyCompany1(DefaultConnectionString1) while User2 point to database MyCompany2(DefaultConnectionString2) and User3 is from MyCompany1 so it should point to (DefaultConnectionString1).
What would be the code to changed it? (most probably after the user login of course - but how?)
My function setContext() doesn't do anything when called or at least doesn't keep the changes. Is it a problem of DI or anything else?
Using Core 2.0.
appSetting.json
{"ConnectionStrings": {"DefaultConnection": "Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=MyDatabaseUser;Data Source=****;MultipleActiveResultSets=true","ConnectionToBeChanged": "Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=MyTemplateDatabase;Data Source=****;MultipleActiveResultSets=true","DefaultConnection1": "Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=MyDatabaseOne;Data Source=****;MultipleActiveResultSets=true","DefaultConnection2": "Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=MyDatabaseTwo;Data Source=****;MultipleActiveResultSets=true","DefaultConnection3": "Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=MyDatabaseThree;Data Source=****;MultipleActiveResultSets=true" } }
Startup.cs
public void ConfigureServices(IServiceCollection services) { // Add our Config object so it can be injected services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddDbContext<ApplicationDataContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConnectionToBeChanged"))); }
ApplicationDataContext.cs public class ApplicationDataContext:DbContext { public ApplicationDataContext(DbContextOptions<ApplicationDataContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<Organisation>() .HasOne(c => c.Parent); } }
BaseController.cs public class BaseController : Controller { private readonly IOptions<AppSettings> appSettings; public ApplicationDataContext _context; private readonly UserManager<ApplicationUser> _userManager; private readonly IHttpContextAccessor _httpContextAccessor; public BaseController(IOptions<AppSettings> AppSettings, ApplicationDataContext Context, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor) { appSettings = AppSettings; _userManager=userManager; _context = Context; _httpContextAccessor = httpContextAccessor; setContext(); } public async void setContext() { if (!_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated ) return; var tmpRole = await _userManager.GetRolesAsync(await _userManager.GetUserAsync(_httpContextAccessor.HttpContext.User)); //ConstantVar.listOfConnectionString Key=> RoleName, Value=> ConnectionString //ConstantVar.listOfConnectionString is build at Startup iterating Configuration.GetSection("ConnectionStrings").AsEnumerable() if (ConstantVar.listOfConnectionString.Keys.Contains(tmpRole.FirstOrDefault().ToUpper())) { var con = ConstantVar.listOfConnectionString[tmpRole.FirstOrDefault().ToUpper()]; var options = new DbContextOptionsBuilder<ApplicationDataContext>(); options.UseSqlServer(con); _context = new ApplicationDataContext(options.Options); } } }
EmployeeController .cs //Inherits from BaseController where it should set the ApplicationDataContext to the User=> Role=>ConnectionString so it point to the correct database public class EmployeeController : BaseController { public EmployeeController(IOptions<AppSettings> appSettings, ApplicationDataContext context, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor) :base(appSettings, context, userManager, httpContextAccessor) { } #region For grid in Index View public JsonResult GetEmployees() { return Json(_context.Employees.OrderBy(o => o.FullName).ToList()); } #endregion // GET: Employees public ActionResult Index() { //Should display the newly assign ConnectionString //Not working as it display the original "ConnectionToBeChanged" string and data. ViewData["Db"] = _context.Database.GetDbConnection().ConnectionString; return View(); }}