This is a kind of similar question that I asked here a few weeks ago with one major change in requirement.
I have a new and unique (I did not find anything like this in my search on the stack) business requirement:
I created two separate entities framework 6 DbContexts that point to two structurally different databases, let's call them PcMaster and PcSubs. Although PcMaster is a direct database, and PcMasterContext will have a static connection string, the PcSubs database is used as a template for creating new databases. Obviously, since these copied databases will have the same exact structure, the idea is to simply change the name of the database (directory) in the connection string to point to another db when the dbcontext instance is created. I also used the repository pattern and dependency injection (currently Ninject, but thinking about switching to Autofac).
I have not seen the IDbContext interface for DbContext unless you want to create it yourself. But then I saw how many said it was not a good idea or a good practice.
Basically, I want that under certain conditions, not only the application should switch between PCMasterContext and PCSubsContext, but also change the connection string to PCSubsContext if PCSubsContext is the current context. The dbContext that I used in the repository should point to a different database. I don't know how to do this with an IoC container like Ninject or Autofac. Here are some code snippets that I have created so far. Help with some real working solutions is much appreciated.
Here is my interface for basic storage
public interface IPCRepositoryBase<T> where T : class { void Add(T entity); void Delete(T entity); T FindOne(Expression<Func<T, bool>> predicate); IQueryable<T> FindBy(Expression<Func<T, bool>> predicate); IQueryable<T> GetAll(); void SetConnection(string connString);
Here is my base repository base
public abstract class PCRepositoryBase<T> : IPCRepositoryBase<T>, IDisposable where T : class { protected readonly IDbSet<T> dbSet; protected DbContext dbCtx; public PCRepositoryBase(DbContext dbCtx) { this.dbCtx = dbCtx; dbSet = dbCtx.Set<T>(); } public void SetConnection(string connString) { dbCtx.Database.Connection.ConnectionString = connString; } public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) { return dbSet.Where(predicate);
And now, here is the interface for one of the resulting repositories:
public interface ISubscriberRepository : IPCRepositoryBase<Subscriber> { IQueryable<Subscriber> GetByStatusName( PCEnums.enumSubsStatusTypes status ); IQueryable<Subscriber> GetByBusinessName( string businessName ); //... //... } public class SubscriberRepository : PCRepositoryBase<Subscriber>, ISubscriberRepository { public SubscriberRepository( DbContext context ) : base( context ) { } public IQueryable<Subscriber> GetByStatusName( PCEnums.enumSubsStatusTypes status ) { return FindBy(x => x.SubsStatusType.Name == status.ToString()); } public IQueryable<Subscriber> GetByBusinessName( string businessName ) { return FindBy( s => s.BusinessName.ToUpper() == businessName.ToUpper() ); } //... other operations omitted for brevity! }
Now my PCSubs dbContext created by the designer:
public partial class PCSubsDBContext : DbContext { public PCSubsDBContext() : base("name=PCSubsDBContext") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } public virtual DbSet<Currency> Currencies { get; set; } public virtual DbSet<DurationName> DurationNames { get; set; } public virtual DbSet<Subscriber> Subscribers { get; set; } }
Is there any way I can just use and / or enter one common dbcontext for both databases along with a connection string for different databases. How can I register a βDbContextβ in an Ioc container without an appropriate interface and still be able to enter a connection string at runtime? Some code examples will really help.