问题
I want to add TWO DbContext in My ASP.NET MVC 5 App, One DbContext For ASPIdentity and The Other For My APP DB. I am Using Repository Pattern. m y problem is, How to To specify the Entity of each DbContext in BaseRepository ? Here Is What I did.
1- DatabaseFactory & IDatabaseFactory
public class DatabaseFactory<T> where T : DbContext,new()
{
private T dbContext;
public T Init()
{
return dbContext ?? (dbContext = new T());
}
}
public interface IDatabaseFactory<T> where T : DbContext
{
T Init();
}
2- IUnitOfWork & UnitOfWork
public class UnitOfWork<T> : IUnitOfWork<T> where T : DbContext
{
private readonly IDatabaseFactory<T> dbFactory;
private T dbContext;
public UnitOfWork(IDatabaseFactory<T> dbFactory)
{
this.dbFactory = dbFactory;
}
protected T DbContext
{
get { return dbContext ?? (dbContext = dbFactory.Init()); }
}
public void Commit()
{
DbContext.SaveChanges();
}
}
public interface IUnitOfWork<T> where T : DbContext, IDisposable
{
void Commit();
}
3- BaseRepository.cs
public abstract class BaseRepository<T> where T : class
{
#region Properties
private DbContext dataContext;
private readonly IDbSet<T> dbSet;
protected IDatabaseFactory DbFactory
{
get;
private set;
}
protected DbContext dbContext
{
get { return dataContext ?? (dataContext = DbFactory.Init()); }
}
#endregion
protected BaseRepository(IDatabaseFactory dbFactory)
{
this.DbFactory = dbFactory;
this.dbSet = this.DbContext.Set<T>();
}
#region Implementation
public virtual void Add(T entity)
{
dbSet.Add(entity);
}
public virtual void Update(T entity)
{
dbSet.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
dbSet.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = dbSet.Where<T>(where).AsEnumerable();
foreach (T obj in objects)
dbSet.Remove(obj);
}
public virtual T GetById(int id)
{
return dbSet.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbSet.ToList();
}
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return dbSet.Where(where).ToList();
}
public T Get(Expression<Func<T, bool>> where)
{
return dbSet.Where(where).FirstOrDefault<T>();
}
#endregion
}
回答1:
I'm also trying to implement generic repository pattern but without UOW.
For creating two DbContext you should add one more type in Base Repository.
Also creation logic for DbFactory should be in UOW only not in BaseRepository.
Here's simplified code for you. And be more specific about what you tried.
2- IUnitOfWork & UnitOfWork
public class UnitOfWork<T1, T2> : IUnitOfWork<T1, T2> where T1 : DbContext where T2 : DbContext {
// FOr DbFactories
private readonly IDatabaseFactory<T1> _dbFactory1;
private readonly IDatabaseFactory<T2> _dbFactory2;
//For Seperate DbContexes
private T _dbContext1;
private T _dbContext2;
public UnitOfWork () {
_dbFactory1 = new DatabaseFactory<T1> ();
_dbFactory2 = new DatabaseFactory<T2> ();
}
//For Accessiong DbContext Objects in Base Repository
protected T DbContext1 {
get { return _dbContext1 ?? (_dbContext1 = _dbFactory1.Init ()); }
}
protected T DbContext2 {
get { return _dbContext2 ?? (_dbContext2 = _dbFactory2.Init ()); }
}
public void Commit () {
DbContext1.SaveChanges ();
DbContext2.SaveChanges ();
}
}
public interface IUnitOfWork<T1, T2> where T1 : DbContext where T2 : DbContext, IDisposable {
void Commit ();
}
}
3 - BaseRepository and Example
public abstract class BaseRepository<T1,T2,T> : IUnitOfWork<T1, T2> where T : class where T1 : DbContext where T2 : DbContext {
#region Properties
// private DbContext _dataContext1; //for first DbContext
// private DbContext _dataContext1; //for second DbContext
private readonly IDbSet<T> _dbSet1; //Going to Perform Operations using Dbsets
private readonly IDbSet<T> _dbSet2;
//For Exposing DbContext to respective Implementing Repositories This is Optional
protected DbContext DataContext1 {
get { return DbContext1; } //retuning DbCOntext Object Created in UOW class
}
protected DbContext DataContext2 {
get { return DbContext2; }
}
//For Exposing DbSets to respective Implementing Repositories This is Optional
protected IDbSet<T> DbSet1 => _dbSet1;
protected IDbSet<T> DbSet2 => _dbSet2;
protected BaseRepository () {
_dbSet1 = DataContext1.Set<T> ();
//OR
_dbSet2 = DataContext2.Set<T> ();
}
#endregion
#region Implementation
#endregion
}
//SPecific Repository Example using Person Class
public class PersonRepository:BaseRepository<AspIdentityDbContext,AppDbContext,Person> {
//can use DbContexes from BaseRepository to write Additional Methods/Queries On dbSets
}
Try this and give feedback.
来源:https://stackoverflow.com/questions/46609214/how-to-add-multi-dbcontext-with-unitofwork-databasefactory-generic-repositor