5

Ho la seguente classe POCO con la relativa implementazione del modello di repository. Se il mio modello è abbastanza grande, sarebbe logico renderlo generico, quindi è necessario eseguire solo un'implementazione.È possibile creare una classe Repository generica per tutti i miei oggetti?

È possibile? Puoi per favore mostrarmi come?

public class Position 
    { 
     [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)] 
     public int PositionID { get; set; } 
     [StringLength(20, MinimumLength=3)] 
     public string name { get; set; } 
     public int yearsExperienceRequired { get; set; } 
     public virtual ICollection<ApplicantPosition> applicantPosition { get; set; } 
    } 


public interface IPositionRepository 
    { 
     void CreateNewPosition(Position contactToCreate); 
     void DeletePosition(int id); 
     Position GetPositionByID(int id); 
     IEnumerable<Position> GetAllPositions(); 
     int SaveChanges(); 
     IEnumerable<Position> GetPositionByCustomExpression(Expression<Func<Position, bool>> predicate); 

    } 

public class PositionRepository : IPositionRepository 
    { 

     private HRContext _db = new HRContext(); 

     public PositionRepository(HRContext context) 
     { 
      if (context == null) 
       throw new ArgumentNullException("context"); 
      _db = context; 
     } 



     public Position GetPositionByID(int id) 
     { 
      return _db.Positions.FirstOrDefault(d => d.PositionID == id); 
     } 

     public IEnumerable<Position> GetAllPosition() 
     { 
      return _db.Positions.ToList(); 
     } 

     public void CreateNewPosition(Position positionToCreate) 
     { 
      _db.Positions.Add(positionToCreate); 
      _db.SaveChanges(); 
     } 

     public int SaveChanges() 
     { 
      return _db.SaveChanges(); 
     } 

     public void DeletePosition(int id) 
     { 
      var posToDel = GetPositionByID(id); 
      _db.Positions.Remove(posToDel); 
      _db.SaveChanges(); 
     } 

     /// <summary> 
     /// Lets suppose we have a field called name, another years of experience, and another department. 
     /// How can I create a generic way in ONE simple method to allow the caller of this method to pass 
     /// 1, 2 or 3 parameters. 
     /// </summary> 
     /// <returns></returns> 
     public IEnumerable<Position> GetPositionByCustomExpression(Expression<Func<Position, bool>> predicate) 
     { 
      return _db.Positions.Where(predicate); 

     } 

     private bool disposed = false; 

     protected virtual void Dispose(bool disposing) 
     { 
      if (!this.disposed) 
      { 
       if (disposing) 
       { 
        _db.Dispose(); 
       } 
      } 
      this.disposed = true; 
     } 

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

risposta

8

sì, è possibile qui è uno:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.Entity; 
using System.Data; 

namespace Nodes.Data.Repository 
{ 
    public class BaseRepository<TEntity>:IRepository<TEntity> where TEntity : class 
    { 
     internal SampleDBContext context; 
     internal DbSet<TEntity> dbSet; 

     public BaseRepository(SampleDBContext context) 
     { 
      this.context = context; 
      this.dbSet = context.Set<TEntity>(); 
     } 

     public virtual TEntity GetByID(object id) 
     { 
      return dbSet.Find(id); 
     } 

     public virtual void Insert(TEntity entity) 
     { 
      dbSet.Add(entity); 

     } 

     public virtual void Delete(object id) 
     { 
      TEntity entityToDelete = dbSet.Find(id); 
      Delete(entityToDelete); 
     } 

     public virtual void DeleteAll(List<TEntity> entities) 
     { 
      foreach (var entity in entities) 
      { 
       this.Delete(entity); 
      } 
     } 

     public virtual void Delete(TEntity entityToDelete) 
     { 
      if (context.Entry(entityToDelete).State == EntityState.Detached) 
      { 
       dbSet.Attach(entityToDelete); 
      } 
      dbSet.Remove(entityToDelete); 
     } 

     public virtual void Update(TEntity entityToUpdate) 
     { 
      dbSet.Attach(entityToUpdate); 
      context.Entry(entityToUpdate).State = EntityState.Modified; 
     } 

     public IQueryable<TEntity> Find(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) 
     { 
      return dbSet.Where(predicate); 
     } 
    } 
} 

UnitOfWork:

public class UnitOfWork 
    { 
     private SampleDBContext context = new SampleDBContext(); 

     private IUserRepository userRepository; 

     #region PublicProperties 

     public IUserRepository UserRepository 
     { 
      get 
      { 
       if (this.userRepository == null) 
       { 
        UserRepository repo = new UserRepository(context); 
       } 
       return userRepository; 
      } 
     } 

     #endregion 

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

     private bool disposed = false; 

     protected virtual void Dispose(bool disposing) 
     { 
      if (!this.disposed) 
      { 
       if (disposing) 
       { 
        context.Dispose(); 
       } 
      } 
      this.disposed = true; 
     } 

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

link per scaricare il modello di progetto che ho scritto.
http://amrelgarhy.com/wp-content/uploads/2011/10/TreeNodesWebsiteTemplate_V1.zip

+0

Non ho bisogno di un dbset.SaveALl() ?? –

+0

Ne hai bisogno, ma nel mio progetto ho usato unità di lavoro per fare questo, incollato il suo codice sopra pure –

+0

Puoi ignorare unitOfWork se vuoi e basta mettere Salva nel repository stesso –

1

Si può provare:

  1. Per utilizzare questo generatore: http://efrepository.codeplex.com/.
  2. Per rendere simili te stesso.
  3. Per generare metodi banali con Visual Studio e aggiungere le query personalizzate in una classe che eredita dal repository.
Problemi correlati