Vasile Mihai
Vasile Mihai

Reputation: 113

Changing dbcontext at runtime depending on the project taken from the database

i'm trying to change the context at runtime depending on the project that i need. For context, i have the following tables:

public class Project : BaseEntity
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public int IconId { get; set; }
        public List<ProjectEnvironment> ProjectEnvironments { get; set; }
        public List<UserProject> UserProjects { get; set; }
        public Icon Icon { get; set; }
    }

and

public class ProjectEnvironment :BaseEntity
    {
        public int ProjectId { get; set; }
        public string EnvironmentName { get; set; }
        public string LogDbConectionString { get; set; }
        public string ConnectionString { get; set; }
        public Project Project { get; set; }

    }

What i need to do is, depending on which project i get from the database, i need to connect to it using the LogDbConnectionString property and do sql queries on that given database.

How can i change the dbContext programatically when both the provider and the connection string can change ? This is my LogDbContext:

public class LogDbContext : DbContext
    {
        public static readonly ILoggerFactory MyLoggerFactory
            = LoggerFactory.Create(builder => { builder.AddConsole(); });

        public LogDbContext() { }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            var serverVersion = ServerVersion.AutoDetect(AppConfig.ConnectionStrings.LogDatabase);
            optionsBuilder.UseMySql(AppConfig.ConnectionStrings.LogDatabase, serverVersion);
            optionsBuilder.UseLoggerFactory(MyLoggerFactory);
        }

        public DbSet<Log> Logs { get; set; }
        public DbSet<Setting> Settings { get; set; }

    }

Upvotes: 1

Views: 797

Answers (1)

Ricardo Rodrigues
Ricardo Rodrigues

Reputation: 482

Here is what I did:

My connection string is given AFTER the identification of the company, user and password, because each user has his own company/database. I store the connection string so I can retrieve it latter and also a boolean variable to check if it is logged or not (static class called MainData).

In my context, I´ve one overrite the Constructors like this:

     public partial class VisioGate22DBContext : DbContext
    {
        /// <summary>
        /// base constructor - for EF migrations
        /// </summary>
        public VisioGate22DBContext() : base()
        {
            Configuration.ProxyCreationEnabled = false;
            if (MainData.VGEngineStatus)
            {
                this.Database.Connection.ConnectionString = MainData.DBContextConnectionString;
            }
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<VisioGate22DBContext, VisioGate22Business.Migrations.Configuration>());
        }

        // <summary>
        // override constructor - connection string
        // </summary>
        // <param name = "UseERPConnectionString" ></ param >
        public VisioGate22DBContext(bool UseERPConnectionString) : base()
        {
            Configuration.ProxyCreationEnabled = false;
            this.Database.Connection.ConnectionString = MainData.DBContextConnectionString;
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<VisioGate22DBContext, VisioGate22Business.Migrations.Configuration>());
        }

        /// <summary>
        /// model creation
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

This has give me the possibility to use my context with or without determining one connection string.

using (VisioGate22DBContext dbContext = new VisioGate22DBContext(true))
{
     res = dbContext.BlaBlaBla.ToList(); //example
}

This is not precisly what you need, but with some twiks I guess you will get there.

Hope this helps...

Upvotes: 1

Related Questions