2017-10-06 102 views
0

我想在我的ASP.NET MVC 5應用程序,ASPIdentity的One DbContext和My APP的其他數據庫中添加兩個DbContext。我正在使用存儲庫模式。 問題是,如何在BaseRepository中指定每個DbContext的實體這是我做的。如何使用UnitOfWork&DatabaseFactory&Generic Repository添加多個DbContext

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 
} 
+0

實體框架'DbContext'類已經使用「工作單元」和「庫」模式了。絕對沒有必要將它包裝在另一組中。如果你正確使用它們,你已經免費獲得這個。 –

回答

0

我也試圖實現通用存儲庫模式,但沒有UOW。
要創建兩個DbContext,您應該在Base Repository中添加一個類型。
DbFactory的創建邏輯應該只在UOW中,而不是在BaseRepository中。
這是您的簡化代碼。並更具體地說明你的嘗試。

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和實施例

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 
} 

嘗試這個和提供反饋。

+0

只需注意實體框架DbContext已經使用「工作單元」模式。絕對沒有必要把它包裝在另一個裏面。 –

+0

@BradleyUffner我同意U.只是回答了問題。 另外我在沒有UOW的情況下實現了這個模式,並在BaseRepository中創建了額外的方法'SAVE'。 – dip4k

相關問題