2011-06-25 14 views
8

Sto cercando ore e ho letto diversi articoli sulla costruzione di repository generici (GR). Per quanto ho capito, i GR sono usati nei casi in cui sono presenti codici simili. Ad esempio, per recuperare una singola riga dalla tabella dal suo id, o l'intera tabella. Tuttavia, ancora, non riesco a capire come realizzarlo.ASP.NET MVC repository generico

public interface IEntity<T> where T : class{ 
    IQueryable<T> getAll(); 
    T GetById(int id); 
} 

public class Repository<T> where T : IEntity<T>{ 
    northWindDataContext nwdc = new northWindDataContext(); 

    public IQueryable<T> getAll() 
    { 
     //code to retrive the whole table 
    } 

    public T GetById(int id) 
    { 
     //code to retrieve a single row (don't know how to do) 
    } 
} 

Poi, voglio fare qualcosa di simile:

Repository<User> rep = new Repository<User>(); 
IQueryable<User> = rep.getAll<User>; 
User user = rep.GetById(35); 

Si prega di qualcuno mi può spiegare come eseguire questa operazione?

risposta

8

Questo è solo uno pseudocodice per creare un repository generico fortemente tipizzato.

public interface IRepository<TEntity> : IDisposable where TEntity : class 
{ 
     IQueryable<TEntity> GetAll { get; } 
     IEntity GetById(int id) { get; } 
} 

public class EntityRepository<TEntity> : IRepository<TEntity> where TEntity : class 
{ 
    private IContext context; 
    private IObjectSet<TEntity> objectSet; 



private IObjectSet<TEntity> ObjectSet 
{ 
     get 
     { 
      if (this.objectSet == null) 
      { 
       var entitySetProperty = this.Context.GetType().GetProperties().Single(p => p.PropertyType.IsGenericType && typeof(IQueryable<>).MakeGenericType(typeof(TEntity)).IsAssignableFrom(p.PropertyType)); 

       this.objectSet = (IObjectSet<TEntity>)entitySetProperty.GetValue(this.Context, null); 
      } 

      return this.objectSet; 
     } 
} 

    public IQueryable<TEntity> GetAll 
     { 
      get 
      { 
       return this.ObjectSet; 
      } 
     } 
} 

Quindi è possibile creare una specifica interfaccia repository dicono

public interface IUserRepository : IRepository<User> 
    { 
    // some additional properties specific to User repository 
    ... 
    } 

    public class UserRepository : EntityRepository<User>, IUserRepository 
    { 
      public UserRepository(IUnitOfWork uow) 
       : base(uow) 
      { 
      }  
    } 

Non so se questo è quello che stai cercando. Questo è se stai usando EF.

+0

Sto usando L2SQL ma ancora ho avuto l'idea, grazie :) – Shaokan

7

Ho utilizzato il repository generico come descritto here. Ho usato il design dell'autore per il mio codice e funziona molto bene. Ecco il codice che ho usato:

IRepository

namespace New_Repository_Design.Repositories 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Data.SqlClient; 
    using System.Linq; 
    using System.Linq.Expressions; 
    using Specifications; 

    public interface IRepository 
    { 
     /// <summary> 
     /// Gets entity by key. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="keyValue">The key value.</param> 
     /// <returns></returns> 
     TEntity GetByKey<TEntity>(object keyValue) where TEntity : class; 

     /// <summary> 
     /// Gets the query. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <returns></returns> 
     IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class; 

     /// <summary> 
     /// Gets the query. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="predicate">The predicate.</param> 
     /// <returns></returns> 
     IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class; 

     /// <summary> 
     /// Gets the query. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     IQueryable<TEntity> GetQuery<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Gets one entity based on matching criteria 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     TEntity Single<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class; 

     /// <summary> 
     /// Gets single entity using specification 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     TEntity Single<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Firsts the specified predicate. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="predicate">The predicate.</param> 
     /// <returns></returns> 
     TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class; 

     /// <summary> 
     /// Gets first entity with specification. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     TEntity First<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Adds the specified entity. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="entity">The entity.</param> 
     void Add<TEntity>(TEntity entity) where TEntity : class; 

     /// <summary> 
     /// Attaches the specified entity. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="entity">The entity.</param> 
     void Attach<TEntity>(TEntity entity) where TEntity : class; 

     /// <summary> 
     /// Deletes the specified entity. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="entity">The entity.</param> 
     void Delete<TEntity>(TEntity entity) where TEntity : class; 

     /// <summary> 
     /// Deletes one or many entities matching the specified criteria 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     void Delete<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class; 

     /// <summary> 
     /// Deletes entities which satify specificatiion 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     void Delete<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Updates changes of the existing entity. 
     /// The caller must later call SaveChanges() on the repository explicitly to save the entity to database 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="entity">The entity.</param> 
     void Update<TEntity>(TEntity entity) where TEntity : class; 

     /// <summary> 
     /// Finds entities based on provided criteria. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Finds entities based on provided criteria. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class; 

     /// <summary> 
     /// Finds one entity based on provided criteria. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     TEntity FindOne<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 

     /// <summary> 
     /// Finds one entity based on provided criteria. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     TEntity FindOne<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class; 

     /// <summary> 
     /// Gets all. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <returns></returns> 
     IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class; 

     /// <summary> 
     /// Gets a collection of entity with paging support 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="orderBy">The order by.</param> 
     /// <param name="pageIndex">Index of the page.</param> 
     /// <param name="pageSize">Size of the page.</param> 
     /// <param name="sortOrder">The sort order.</param> 
     /// <returns></returns> 
     IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class; 

     /// <summary> 
     /// Gets a collection of entity base on criteria with paging support 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <param name="orderBy">The order by.</param> 
     /// <param name="pageIndex">Index of the page.</param> 
     /// <param name="pageSize">Size of the page.</param> 
     /// <param name="sortOrder">The sort order.</param> 
     /// <returns></returns> 
     IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, bool>> criteria, Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class; 

     /// <summary> 
     /// Gets entities which satify specification 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <param name="orderBy">The order by.</param> 
     /// <param name="pageIndex">Index of the page.</param> 
     /// <param name="pageSize">Size of the page.</param> 
     /// <param name="sortOrder">The sort order.</param> 
     /// <returns></returns> 
     IEnumerable<TEntity> Get<TEntity>(ISpecification<TEntity> criteria, Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class; 

     /// <summary> 
     /// Counts the specified entities. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <returns></returns> 
     int Count<TEntity>() where TEntity : class; 

     /// <summary> 
     /// Counts entities with the specified criteria. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     int Count<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class; 

     /// <summary> 
     /// Counts entities satifying specification. 
     /// </summary> 
     /// <typeparam name="TEntity">The type of the entity.</typeparam> 
     /// <param name="criteria">The criteria.</param> 
     /// <returns></returns> 
     int Count<TEntity>(ISpecification<TEntity> criteria) where TEntity : class; 
    } 
} 

DomainRepository

namespace New_Repository_Design.Repositories 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Data; 
    using System.Data.Entity.Design.PluralizationServices; 
    using System.Data.Objects; 
    using System.Data.SqlClient; 
    using System.Globalization; 
    using System.Linq; 
    using System.Linq.Expressions; 
    using Specifications; 

    public sealed class DomainRepository : IRepository 
    { 
     private readonly PluralizationService _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en")); 

     private readonly string _connectionStringName; 
     private ObjectContext _objectContext; 

     /// <summary> 
     /// Initializes a new instance of the <see cref="GenericRepository&lt;TEntity&gt;"/> class. 
     /// </summary> 
     public DomainRepository() 
      : this(string.Empty) 
     { 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="GenericRepository&lt;TEntity&gt;"/> class. 
     /// </summary> 
     /// <param name="connectionStringName">Name of the connection string.</param> 
     public DomainRepository(string connectionStringName) 
     { 
      this._connectionStringName = connectionStringName; 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="GenericRepository"/> class. 
     /// </summary> 
     /// <param name="objectContext">The object context.</param> 
     public DomainRepository(ObjectContext objectContext) 
     { 
      if (objectContext == null) 
       throw new ArgumentNullException("objectContext"); 
      this._objectContext = objectContext; 
     } 

     public TEntity GetByKey<TEntity>(object keyValue) where TEntity : class 
     { 
      EntityKey key = GetEntityKey<TEntity>(keyValue); 

      object originalItem; 
      if (ObjectContext.TryGetObjectByKey(key, out originalItem)) 
      { 
       return (TEntity)originalItem; 
      } 
      return default(TEntity); 
     } 

     public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class 
     { 
      var entityName = GetEntityName<TEntity>(); 
      var q = ObjectContext.CreateQuery<TEntity>(entityName); 
      //return ObjectContext.CreateQuery<TEntity>(entityName); 
      return q; 
     } 

     public IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class 
     { 
      return GetQuery<TEntity>().Where(predicate); 
     } 

     public IQueryable<TEntity> GetQuery<TEntity>(ISpecification<TEntity> specification) where TEntity : class 
     { 
      return specification.SatisfyingEntitiesFrom(GetQuery<TEntity>()); 
     } 

     public IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class 
     { 
      if (sortOrder == SortOrder.Ascending) 
      { 
       return GetQuery<TEntity>().OrderBy(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
      } 
      return GetQuery<TEntity>().OrderByDescending(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
     } 

     public IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class 
     { 
      if (sortOrder == SortOrder.Ascending) 
      { 
       return GetQuery<TEntity>().Where(predicate).OrderBy(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
      } 
      return GetQuery<TEntity>().Where(predicate).OrderByDescending(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
     } 

     public IEnumerable<TEntity> Get<TEntity>(ISpecification<TEntity> specification, Expression<Func<TEntity, string>> orderBy, int pageIndex, int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class 
     { 
      if (sortOrder == SortOrder.Ascending) 
      { 
       return specification.SatisfyingEntitiesFrom(GetQuery<TEntity>()).OrderBy(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
      } 
      return specification.SatisfyingEntitiesFrom(GetQuery<TEntity>()).OrderByDescending(orderBy).Skip(pageIndex).Take(pageSize).AsEnumerable(); 
     } 

     public TEntity Single<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class 
     { 
      return GetQuery<TEntity>().SingleOrDefault<TEntity>(criteria); 
     } 

     public TEntity Single<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      return criteria.SatisfyingEntityFrom(GetQuery<TEntity>()); 
     } 

     public TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class 
     { 
      return GetQuery<TEntity>().FirstOrDefault(predicate); 
     } 

     public TEntity First<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      return criteria.SatisfyingEntitiesFrom(GetQuery<TEntity>()).FirstOrDefault(); 
     } 

     public void Add<TEntity>(TEntity entity) where TEntity : class 
     { 
      if (entity == null) 
      { 
       throw new ArgumentNullException("entity"); 
      } 
      ObjectContext.AddObject(GetEntityName<TEntity>(), entity); 
     } 

     public void Attach<TEntity>(TEntity entity) where TEntity : class 
     { 
      if (entity == null) 
      { 
       throw new ArgumentNullException("entity"); 
      } 

      ObjectContext.AttachTo(GetEntityName<TEntity>(), entity); 
     } 

     public void SaveChanges() 
     { 
      this.ObjectContext.SaveChanges(); 
     } 

     public void Delete<TEntity>(TEntity entity) where TEntity : class 
     { 
      if (entity == null) 
      { 
       throw new ArgumentNullException("entity"); 
      } 
      ObjectContext.DeleteObject(entity); 
     } 

     public void Delete<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class 
     { 
      IEnumerable<TEntity> records = Find<TEntity>(criteria); 

      foreach (TEntity record in records) 
      { 
       Delete<TEntity>(record); 
      } 
     } 

     public void Delete<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      IEnumerable<TEntity> records = Find<TEntity>(criteria); 
      foreach (TEntity record in records) 
      { 
       Delete<TEntity>(record); 
      } 
     } 

     public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class 
     { 
      return GetQuery<TEntity>().AsEnumerable(); 
     } 

     public void Update<TEntity>(TEntity entity) where TEntity : class 
     { 
      var fqen = GetEntityName<TEntity>(); 

      object originalItem; 
      EntityKey key = ObjectContext.CreateEntityKey(fqen, entity); 
      if (ObjectContext.TryGetObjectByKey(key, out originalItem)) 
      { 
       ObjectContext.ApplyCurrentValues(key.EntitySetName, entity); 
      } 
     } 

     public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class 
     { 
      return GetQuery<TEntity>().Where(criteria); 
     } 

     public TEntity FindOne<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class 
     { 
      return GetQuery<TEntity>().Where(criteria).FirstOrDefault(); 
     } 

     public TEntity FindOne<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      return criteria.SatisfyingEntityFrom(GetQuery<TEntity>()); 
     } 

     public IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      return criteria.SatisfyingEntitiesFrom(GetQuery<TEntity>()); 
     } 

     public int Count<TEntity>() where TEntity : class 
     { 
      return GetQuery<TEntity>().Count(); 
     } 

     public int Count<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class 
     { 
      return GetQuery<TEntity>().Count(criteria); 
     } 

     public int Count<TEntity>(ISpecification<TEntity> criteria) where TEntity : class 
     { 
      return criteria.SatisfyingEntitiesFrom(GetQuery<TEntity>()).Count(); 
     } 

     private ObjectContext ObjectContext 
     { 
      get 
      { 
       return this._objectContext; 
      } 
     } 

     private string GetEntityName<TEntity>() where TEntity : class 
     { 
      return string.Format("{0}.{1}", ObjectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(TEntity).Name)); 
     } 

     private EntityKey GetEntityKey<TEntity>(object keyValue) where TEntity : class 
     { 
      var entitySetName = GetEntityName<TEntity>(); 
      var objectSet = ObjectContext.CreateObjectSet<TEntity>(); 
      var keyPropertyName = objectSet.EntitySet.ElementType.KeyMembers[0].ToString(); 
      var entityKey = new EntityKey(entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) }); 
      return entityKey; 
     } 
    } 
}` 

Ad esempio, per ottenere un elemento da esso è ID.

DomainRepository.FindOne<User>(u => u.Id == userId);

restituirà un singolo utente. O

DomainRepository.Find<User>(u => u.UserName.Contains("Blah"));

Esperimento con questo repository, vedere se si tratta di suite vostre esigenze.

+0

Mi piace molto questo – AndreMiranda

Problemi correlati