0

Entity Framework 6.0とリポジトリデザインパターンを使用して、プロジェクトを管理するためのASP.NET MVCアプリケーションを開発しました。ここでは、トランザクションを統合して、一部の挿入/更新データベース操作が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.マイIコンテキスト:以下

は私の一般的なリポジトリのスニペットです実装

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

スタックオーバーフローでは、この質問はあまりにも幅広く、主に意見に基づいて行われます。コード自体に問題のない* working *コードなので、[CodeReview](http://codereview.stackexchange.com/help/how-to-ask)はこの質問に適しているかもしれません。 –

+0

意見: 'SaveChanges'はリポジトリに属していません。作業単位なしではできません。 –

答えて

2

通常、リポジトリはエンジン/サービスクラスに注入されます。 ProjectRepoとTaskRepoが注入されているProjectEngine.csがあると仮定します。コードは次のようになります

 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

私はあなたからもっと知りたいと思います。 EFリポジトリとの取引をどのように管理していますか? –

関連する問題