Questa è una specie di domanda simile che ho chiesto a here alcune settimane fa con un cambiamento significativo nel requisito.Utilizzo di più istanze di dbcontext e dipendenza dipendenza
Ho un nuovo e unico (non ho trovato nulla di simile nella mia ricerca StackOverflow) requisito aziendale:
ho creato due distinte Entity Framework 6 DbContexts che puntano a due database strutturalmente diverse, cerchiamo di chiamata loro PcMaster e PcSubs. Mentre PcMaster è un database semplice e PcMasterContext avrà una stringa di connessione statica, il database PcSubs viene utilizzato come modello per creare nuovi database. Ovviamente, dal momento che questi database copiati avranno la stessa struttura esatta, l'idea è di cambiare semplicemente il nome del database (catalogo) nella stringa di connessione per puntare a un db differente quando viene creato il dbcontext. Ho anche utilizzato il pattern di repository e l'iniezione delle dipendenze (attualmente Ninject, ma pensando di passare ad Autofac).
Non ho visto un'interfaccia IDbContext per DbContext, a meno che non si desideri crearne uno da soli. Ma poi, ho visto molti dire che non è una buona idea o non la migliore pratica.
In sostanza, ciò che voglio fare è, in determinate condizioni, non solo l'applicazione deve passare tra PCMasterContext e PCSubsContext, ma anche modificare la stringa di connessione in PCSubsContext se PCSubsContext è il contesto corrente. il dbContext che ho usato nel repository deve puntare a un database differente. Non so come posso farlo con un contenitore IoC come Ninject o Autofac. Ecco alcuni frammenti di codice che ho creato finora. L'aiuto con alcune soluzioni di lavoro reali è molto apprezzato.
Qui è la mia interfaccia per il repository di base
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);
//...
//...
}
Qui è la mia base astratta repository
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); // DataContext.Set<T>().Where(predicate );
}
public virtual IQueryable<T> GetAll()
{
return dbSet;
}
public T FindOne(Expression<Func<T, bool>> predicate)
{
return dbSet.SingleOrDefault(predicate);
}
//... Not all implementations listed
//...
}
Ed ora, ecco l'interfaccia per uno dei repository derivati:
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!
}
Ora, il mio PCSub dbContext generato dal 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; }
}
C'è un modo, posso solo utilizzare e/o iniettare un dbcontext generico per entrambi i database con la stringa di connessione per diversi database. Come dovrei registrare "DbContext" nel contenitore Ioc senza un'interfaccia corrispondente ed essere ancora in grado di iniettare la stringa di connessione in fase di runtime? Alcuni esempi di codice saranno davvero utili.
Grazie Steven. Questo ha funzionato perfettamente. –