0

我開發了一個ASP.NET MVC應用程序來管理項目,使用實體框架6.0和存儲庫設計模式。現在我想集成事務,以確保某些插入/更新數據庫操作遵守ACID主體,尤其是原子性主體。與存儲庫設計模式交易

下面是我的通用倉庫的一個片段:

1.通用倉庫接口

public interface IGenericRepository<T> : IRepository where T : BaseEntity 
    { 
     void Create(T entity); 
     void Delete(T entity); 
     IEnumerable<T> GetAll(); 
     void Update(T entity); 
    } 

2.通用倉儲類

public abstract class GenericRepository<T> : IGenericRepository<T> where T : BaseEntity 
     { 
      protected IContext _context; 
      protected IDbSet<T> _dbset; 

      public GenericRepository(IContext context) 
      { 
       _context = context; 
       _dbset = _context.Set<T>(); 
      } 


      public virtual void Create(T entity) 
      { 
       if (entity == null) 
       { 
        throw new ArgumentNullException("entity"); 
       } 

       _dbset.Add(entity); 
       _context.SaveChanges(); 
      } 


      public virtual void Update(T entity) 
      { 
       if (entity == null) throw new ArgumentNullException("entity"); 
       _context.Entry(entity).State = System.Data.Entity.EntityState.Modified; 
       _context.SaveChanges(); 
      } 

      public virtual void Delete(T entity) 
      { 
       if (entity == null) throw new ArgumentNullException("entity"); 
       _dbset.Remove(entity); 
       _context.SaveChanges(); 
      } 

      public virtual IEnumerable<T> GetAll() 
      { 
       return _dbset.AsEnumerable<T>(); 
      } 
     } 

3.我Icontext實施

public interface IContext 
    { 
     IDbSet<Projet> Projects { get; set; }  
     IDbSet<Task> Tasks{ get; set; } 
     IDbSet<Entite> Entities { get; set; } 

     DbSet<TEntity> Set<TEntity>() where TEntity : class; 
     DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class; 

     int SaveChanges(); 
    } 

4.項目實體

public class ProjectRepository : GenericRepository<Projet>, IProjectRepository 
    { 

     IContext _context; 

     public ProjectRepository(IContext context) : base(context) 
     { 
      _context = context; 
      _dbset = _context.Set<Projet>(); 
     } 

     public Projet GetProjectById(int Id) 
     { 
      return _dbset.FirstOrDefault(x=>x.Id == Id); 
     } 

    } 

所以,我想要做的,是有交易與上面的模型工作。 例如,當用他的任務創建項目時,我想使用事務來保存項目和任務實體,所以我確信插入這些實體將是一個原子操作。

感謝您的幫助和建議。

+0

http://stackoverflow.com/questions/575136/transactions-in-the-repository-pattern可能有幫助 – Kaushal

+0

在Stack Overflow中,這個問題過於寬泛或主要是基於觀點。由於它的代碼本身沒有問題,所以[CodeReview](http://codereview.stackexchange.com/help/how-to-ask)可能更適合這個問題。 –

+0

至於意見:'SaveChanges'不屬於存儲庫。你離不開一個工作單位。 –

回答

2

通常,您的存儲庫被注入到引擎/服務類中。我將假設我們有一個ProjectEngine.cs,其中ProjectRepo和TaskRepo被注入。代碼如下所示:

 public class ProjectEngine : IProjectEngine 
     { 
      IProjectRepository projectRepository; 
      ITaskRepository taskRepository; 

      public ProjectEngine(
       IProjectRepository ProjectRepository, 
       ITaskRepository TaskRepository) 
      { 
       projectRepository = ProjectRepository; 
       taskRepository = TaskRepository; 
      } 

      public void CreateProject(CreateProjectRequest createProjectRequest) 
      { 

      using (TransactionScope scope = new TransactionScope()) 
        { 

         // these operations are atomic since they below to same transactionscope 
         projectRepository.Add([project]); 
         taskRepository.Add([tasks]); 
         // data will not be affected until complete operation is called. Any database exception would rollback the transaction. 
         scope.Complete(); 
        } 

       } 

     } 

回顧一下,最好的方法是在同一個transactionscope中包含多個存儲庫操作。

+0

感謝Houssam,很好的解決方案! –

+0

'TransactionScope'是一個不良設計的解決方案。 –

+0

我想知道更多來自你的Gert。請與我們分享您如何管理EF存儲庫的交易。 –