How to add multi DbContext With UnitOfWork & DatabaseFactory & Generic Repository

可紊 提交于 2019-12-23 04:57:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!