2014-09-28 10 views
5

ASP.NET MVC kullanarak Entity Framework 6 (Kod İlk/POCO) ile bir web uygulaması geliştirmeyi planlıyorum. Ayrıca, başvurumda genel Depo ve Çalışma Düzeni'ni kullanmak istiyorum. Bu uygulama ikiden fazla veritabanına bağlanır, bu yüzden uygulamada birden çok DbContext kullanmam gerekir.Çoklu DbContext ile Çalışma Kalıbı ve Çalışma Kalıbının En İyi Uygulaması

public class ContextOne : DbContext 
{ 
    public DbSet<Model_One1> 
    public DbSet<Model_One2> 
} 

public class ContextTwo : DbContext 
{ 
    public DbSet<Model_Two1> 
    public DbSet<Model_Two2> 
} 

public class ContextThree : DbContext 
{ 
    public DbSet<Model_Three1> 
    public DbSet<Model_Three2> 
} 

public interface IRepository<T> where T : DbContext 
{ 
    void Add<T>(T entity) where T : class; 
} 

public class Repository<T> where T : DbContext 
{ 
    void Add<T>(T entity) where T : class 
    { 
     //T is DbContext and Model. So confusing 
    } 
} 

public interface IUnitOfWork<IRepository> 
{ 
} 

public class UnitOfWork<IRepository> 
{ 
    //IRepository contains more than one DbContext how can I initiate them here? 
} 

//in application should look like this 
public class BaseController : Controller 
{ 
    protected IRepository repository = new .. //here I have no idea with multiple DbContext 
} 

public class HomeController : BaseController 
{ 
    public ActionResult Add(Model_Two2 model) 
    { 
     base.repository.Add<Model_Two2>(model) 
    } 
} 

ben eşleşen bağlamı bilebilir nasıl Denetleyicisi'nden IRepository ve IUnitOfWork ararsanız? Bu sorunun en iyi pratiği nedir?

cevap

6

Ben DBContext kabul etmek için bir Oluşturucu parametresi ile UnitOfWork deseni oluşturmak için size öneririm -

public interface IDbContext 
{ 
    IDbSet<T> Set<T>() where T : class; 
    int SaveChanges(); 
    void Dispose(); 
} 

Ve depo uygulaması olacak - - IDbContext olduğunu

public class UnitOfWork : IUnitOfWork 
{ 
    private readonly IDbContext _context; 

    private bool _disposed; 
    private Hashtable _repositories; 

    public UnitOfWork(IDbContext context) 
    { 
     _context = context; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    public void Save() 
    { 
     _context.SaveChanges(); 
    } 

    public virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
      if (disposing) 
       _context.Dispose(); 

     _disposed = true; 
    } 

    public IRepository<TEntity> Repository<TEntity>() where TEntity : class 
    { 
     if (_repositories == null) 
      _repositories = new Hashtable(); 

     var type = typeof(TEntity).Name; 

     if (_repositories.ContainsKey(type)) return (IRepository<TEntity>) _repositories[type]; 

     var repositoryType = typeof (Repository<>); 

     var repositoryInstance = 
      Activator.CreateInstance(repositoryType 
       .MakeGenericType(typeof (TEntity)), _context); 

     _repositories.Add(type, repositoryInstance); 

     return (IRepository<TEntity>) _repositories[type]; 
    } 
} 

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
    { 
     internal IDbContext Context; 
     internal IDbSet<TEntity> DbSet; 

     public Repository(IDbContext context) 
     { 
      Context = context; 
      DbSet = context.Set<TEntity>(); 
     } 

     public virtual TEntity FindById(object id) 
     { 
      return DbSet.Find(id); 
     } 

     public virtual void Update(TEntity entity) 
     { 
      DbSet.Attach(entity); 
     } 
     public virtual void Delete(object id) 
     { 
      var entity = DbSet.Find(id); 
      var objectState = entity as IObjectState; 
      if (objectState != null) 
       objectState.State = ObjectState.Deleted; 
      Delete(entity); 
     } 

     public virtual void Delete(TEntity entity) 
     { 
      DbSet.Attach(entity); 
      DbSet.Remove(entity); 
     } 

     public virtual void Insert(TEntity entity) 
     { 
      DbSet.Attach(entity); 
     } 

     public virtual List<TEntity> GetAll() 
     { 
      return DbSet.ToList(); 
     } 
    } 

Bu yaklaşımla bağımsız DBContext için bir UnitOfWork oluşturabilirsiniz. ve UnitOfWork'ta işlem yapmak veya geri almak için belirli bir mantığa sahipsiniz.

+0

BaseController'ımda IRepository ve IUnitOfWork'u nasıl aramalıyım? Her model için yüzlerce Dozlama örneği oluşturmalı mıyım? Örneğin, 'İpi deposu' Student = new Deposu () 'vb, vb. – derodevil

+0

" BaseController "ın bir UoW ​​başlatmak için doğru yer olacağını sanmıyorum. Bunun yerine, iş süreci seviyenizde talep bazında oluşturulmalıdır. Bu nedenle, gereksinim esasına göre DbContexts temelli özel UoW oluşturun ve ardından belirli depoları edinin. – ramiramilu

+0

'UnitOfWork'unuzda bir yok edici ve yönetilmeyen kaynak bulunmadığından' GC.SuppressFinalize (this) 'olarak adlandırmak zorunda kalmazsınız ve atma düzenini uygulamak zorunda kalmazsınız. UnitOfWork.Dispose'da sadece '_context.Dispose()' i çağırmanız gerekir – Albert

0

Ben herşey yolunda ise istisna ActionContext orada olup olmadığını, hareketi tamamlamak OnActionExecuting ben işlem açmak bir ActionAttribute olarak UnitOfWork ve OnActionExecuted uygulanmasını üstlenirken, işlem geri alınır edilmelidir.

Zor olan şey, 2 DbContexts sahip olmasıdır. Bence, dbContexts tembel yaratılmış olmalı. Bir çeşit bayrak değişkeni tanıtın ve UnitOfWork.OnActionExecuting numaralı telefondan True'a ayarlayın. Daha sonra, ilk kez dbContext'e dokunduğunuzda, UnitOfWork ile ilgili olup olmadığınızı kontrol etmeli ve eğer evet ise, bu özel dbContext için işlem açmalısınız. Tüm açık işlemler, UnitOfWork.ActionExecuted'dan erişilebilen bir Listeye konabilir. Son olarak, ActionContext'te herhangi bir özel durum olup olmadığını kontrol edin: evet - Rollback, no - Commit.

+0

Yükleme ve Geri Alma işlemi için sorun yok. Uygulamamın aynı ve farklı sunuculardaki birden çok veritabanına bağlanması gerektiğinden, birden çok DbContext ile Repsitory ve UoW modeli oluşturma konusunda en iyi uygulama hakkında bir açıklamaya ihtiyacım var. Tek bir UoW'un tek bir genel depo ile bu DbContexts işlemek istiyorum istiyorum. – derodevil

İlgili konular