2017-10-06 96 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

相关问题