如何使用UnitOfWork&添加多个DbContext DatabaseFactory&通用存储库

时间:2017-10-06 15:32:31

标签: c# repository-pattern unit-of-work

我想在My ASP.NET MVC 5应用程序中添加两个DbContext,为ASPIdentity添加一个DbContext,为我的APP DB添加另一个DbContext。我正在使用存储库模式。 问题是,如何在BaseRepository中指定每个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&amp;的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 个答案:

答案 0 :(得分:0)

我也试图实现通用的存储库模式但没有UOW 要创建两个DbContext,您应该在Base Repository中再添加一个类型 此外,DbFactory的创建逻辑应该只在UOW中,而不是在BaseRepository中 这是您的简化代码。并且更具体地说明你的尝试。

2- IUnitOfWork&amp;的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
}

试试这个并提供反馈。