2017-10-06 7 views
0

My ASP.NET MVC 5 Appに1つのDbContextを、ASPIdentityに1つのDbContextを、My APP DBに1つのDbContextを追加します。私はリポジトリパターンを使用しています。 問題は、BaseRepositoryの各DbContextのエンティティを指定する方法ここは私がしたことです。UnitOfWork&DatabaseFactory&Genericリポジトリを使用してマルチ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

Entity Frameworkの 'DbContext'クラスは、「Unit of Work」と「Repository」パターンを使用しています。それを別のセットの中にラップする必要は全くありません。それらを正しく使用すれば、すでに無料で入手できます。 –

答えて

0

私はまた、汎用リポジトリパターンを実装しようとしていますが、UOWは実装していません。
2つのDbContextを作成するには、もう1つのタイプをベースリポジトリに追加する必要があります。
また、DbFactoryの作成ロジックは、BaseRepositoryではなくUOWでなければなりません。
ここでは簡単なコードを紹介します。そして、あなたが試したことについてもっと具体的にしてください。

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

Entity Frameworkの 'DbContext'が「Unit of Work」パターンを使用していることに注意してください。それを別のものの中に包む必要は全くありません。 –

+0

@BradleyUffner私はUに同意します。 また、UOWなしでこのパターンを実装し、BaseRepositoryで追加のメソッド 'SAVE'を作成しています。 – dip4k

関連する問題