0

Ich habe eine ASP.NET MVC-Anwendung entwickelt, um Projekte mithilfe von Entity Framework 6.0 und dem Repository-Entwurfsmuster zu verwalten. Jetzt möchte ich Transaktionen integrieren, um sicherzustellen, dass einige Operationen zum Einfügen/Aktualisieren von Datenbanken den ACID-Principal und insbesondere den Atomity-Principal respektieren.Transaktion mit den Repository-Entwurfsmustern

Nachfolgend finden Sie eine Schnipsel meines Allgemein Repository:

1. Allgemeine Repository-Schnittstelle

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

2. Generisches Repository Klasse

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. Mein Icontext Implementierung

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. Das Projekt Entity

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

    } 

Also, was ich tun möchte, ist Geschäfte mit dem Modell arbeiten müssen oben. Wenn beispielsweise ein Projekt mit seinen Aufgaben erstellt wird, möchte ich eine Transaktion verwenden, um die Projekt- und die Task-Entitäten zu speichern. Daher bin ich mir sicher, dass die Einfügung dieser Entitäten eine atomare Operation wäre.

danke für Ihre Hilfe und Vorschläge.

+0

http://stackoverflow.com/questions/575136/transactions-in-the-repository-pattern kann helfen – Kaushal

+0

Bei Stack Overflow geht diese Frage als zu breit oder primär auf Meinung basiert. Da Code * ohne Code-Probleme im Code selbst arbeitet, ist [CodeReview] (http://codereview.stackexchange.com/help/how-to-ask) möglicherweise besser für diese Frage geeignet. –

+0

Wie für Meinungen: 'SaveChanges' gehört nicht in ein Repository. Auf eine Arbeitseinheit kann man nicht verzichten. –

Antwort

2

Normalerweise werden Ihre Repositories in Engine/Service-Klassen eingefügt. Ich nehme an, wir haben eine ProjectEngine.cs, wo ProjectRepo und TaskRepo injiziert werden. Der Code wird wie folgt aussehen:

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

       } 

     } 

Zur Erinnerung, ist der beste Weg, dies zu tun, ist durch mehr Repositories Operationen innerhalb derselben Transaction darunter.

+0

Danke Houssam, gute Lösung! –

+0

'TransactionScope' ist ein Workaround für schlechtes Design. –

+0

Ich würde gerne mehr von dir wissen Gert. Bitte teilen Sie uns mit, wie Sie Transaktionen mit EF-Repositories verwalten. –

Verwandte Themen