0

J'ai développé une application ASP.NET MVC pour gérer des projets, en utilisant Entity Framework 6.0 et le modèle de conception Repository. Maintenant, je veux intégrer les transactions afin d'assurer que certaines opérations de base de données d'insertion/mise à jour respectent le principal ACID et en particulier le principal de l'atomicité.Transaction avec les modèles de conception de référentiels

Voici un extraits de mon dépôt générique:

1. Interface référentiel générique

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

2. classe référentiel générique

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. Mon Icontext mise en oeuvre

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. Le projet Entité

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); 
     } 

    } 

Alors, ce que je veux faire, est d'avoir des transactions travailler avec le modèle ci-dessus. Par exemple, quand un projet est créé avec ses tâches, je veux utiliser une transaction pour sauvegarder le Projet et les entités Tâche, donc je suis sûr que l'insertion de ces entités serait une opération atomique.

merci pour votre aide et vos suggestions.

+0

http://stackoverflow.com/questions/575136/transactions-in-the-repository-pattern peut vous aider – Kaushal

+0

Chez Stack Overflow, cette question est trop générale ou basée principalement sur l'opinion. Comme c'est du code * working * sans problèmes dans le code lui-même, [CodeReview] (http://codereview.stackexchange.com/help/how-to-ask) peut être mieux adapté à cette question. –

+0

En ce qui concerne les avis: 'SaveChanges' n'appartient pas à un référentiel. Vous ne pouvez pas faire sans une unité de travail. –

Répondre

2

Généralement, vos référentiels sont injectés dans les classes de moteur/service. Je suppose que nous avons un ProjectEngine.cs où ProjectRepo et TaskRepo sont injectés. Le code se penchera comme suit:

 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(); 
        } 

       } 

     } 

Pour récapituler, la meilleure façon de le faire est en incluant les opérations multiples référentiels au sein même TransactionScope.

+0

Merci Houssam, bonne solution! –

+0

'TransactionScope' est une solution de contournement pour mauvaise conception. –

+0

Je voudrais en savoir plus de vous Gert. Veuillez nous indiquer comment gérer les transactions avec les référentiels EF. –