2011-06-25 20 views
8

Estoy buscando durante horas y he leído varios artículos sobre la construcción de repositorios genéricos (GR). Por lo que he entendido, los RR.GG. se usan en casos en que hay códigos similares. Por ejemplo, para obtener una sola fila de la tabla por su id o toda la tabla. Sin embargo, aún así, no puedo entender cómo darme cuenta de esto.Repositorio genérico ASP.NET MVC

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

Entonces, quiero hacer algo similar:

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

Por favor alguien me puede explicar cómo llevar a cabo esta tarea?

Respuesta

8

Esto es solo un pseudocódigo para crear un repositorio genérico fuertemente tipado.

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

continuación, puede crear una interfaz específica repositorio dicen

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

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

No sabe si esto es lo que estás buscando. Esto es si estás usando EF.

+0

Estoy usando L2SQL pero aún tengo la idea, gracias :) – Shaokan

7

He estado usando el repositorio genérico como se describe here. He estado usando el diseño del autor para mi código, y funciona muy bien. Aquí está el código que he estado usando:

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

Por ejemplo, para obtener un elemento por su ID.

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

devolverá un solo usuario. O

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

Experimento con este repositorio, ver si se trata de habitaciones sus necesidades.

+0

Me gusta mucho de esta manera – AndreMiranda

Cuestiones relacionadas