Reputation: 1253
All,
I'm using Unit Of Work and Generic Repository patterns for data access in my ASP.NET MVC app with Entity Framework 5. My app worked fine when I only had to deal with 1 database and DbContext.
My problem is, I have a second not-very-closely-related database I need data access for, so I'm assuming I need a second DbContext. However, I don't know how to refactor my Generic Repository to accommodate more than one DbContext. Help!
Here's a simplified look at what I'm attempting so with comments explaining what's failing:
public class UnitOfWork
{
private Db1Entities db1Context = new Db1Entities();
private Db2Entities db2Context = new Db2Entities();
public GenericRepository<ObjectA> ObjectARepository { // ObjectA is sourced from database 1, so it uses a different DbContext than ObjectB.
get {
return new GenericRepository<ObjectA>(db1Context);
}
}
public GenericRepository<ObjectB> ObjectBRepository { // ObjectB is sourced from database 2, so it uses a different DbContext than ObjectA.
get {
return new GenericRepository<ObjectB>(db2Context);
}
}
}
public class GenericRepository<T> where T : class
{
internal DbContext context; // This line and the GenericRepository constructor are my problem. Type DbContext, being a base class, doesn't have the db objects that Db1Entities or Db2Entities have.
// When I used to only have to manage 1 DbContext, "context" was type Db1Entities and it worked fine.
internal DbSet<T> dbSet;
public GenericRepository(DbContext context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
FYI this is what I'm doing to get by for now. I don't consider it a solution because I'm duplicating "GenericRepository" by copying it as 2 generic repositories, each designed for a different DbContext. I think I ought to be able to use "GenericRepository" and be able to pass it a DbContext rather than making a GenericRepository class for each DbContext... I just don't know how to make it work. See below:
public class UnitOfWork
{
private Db1Entities db1Context = new Db1Entities();
private Db2Entities db2Context = new Db2Entities();
public GenericDb1Repository<ObjectA> ObjectARepository { // ObjectA is sourced from database 1, so it uses a different DbContext than ObjectB.
get {
return new GenericDb1Repository<ObjectA>(db1Context);
}
}
public GenericDb2Repository<ObjectB> ObjectBRepository { // ObjectB is sourced from database 2, so it uses a different DbContext than ObjectA.
get {
return new GenericDb2Repository<ObjectB>(db2Context);
}
}
}
public class GenericDb1Repository<T> where T : class
{
internal Db1Entities context;
internal DbSet<T> dbSet;
public GenericRepository(Db1Entities context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
public class GenericDb2Repository<T> where T : class
{
internal Db2Entities context;
internal DbSet<T> dbSet;
public GenericRepository(Db2Entities context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}
Upvotes: 2
Views: 1721
Reputation: 88
public class GenericDb1Repository<T, TContext>
where T : class
where TContext : DbContext, new()
{
internal TContext context;
internal DbSet<T> dbSet;
public GenericRepository(TContext context) {
this.context = context;
this.dbSet = context.set<T>();
}
public virtual T GetByID (int id) {
// code to return a T object by id...
}
// Other repository methods...
}**
Upvotes: 1