简体   繁体   中英

Entity Framework 5 - multiple DbContext and a Generic Repository class

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...
}
    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...
}**

@serverus_92 Good handle, but it will be made repository class more complicated.

In this case, I think we can use multiple GenericRpository for each for specific Context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM