2011-06-25 50 views
8

我正在寻找几个小时,并阅读了关于构建通用存储库(GR)的几篇文章。就我所了解的情况而言,当存在类似代码时,使用GRs。例如,通过它的id或整个表从表中读取一行。但是,我仍然无法理解如何实现这一点。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) 
    } 
} 

然后,我希望做同样的事情:

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

请任何人都可以解释我如何完成这个任务?

回答

8

这只是一个伪代码来创建一个强类型的通用资源库。

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

然后,您可以创建一个特定的仓库接口说

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

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

不知道如果这是你在找什么。这是如果你使用EF。

+0

我正在使用L2SQL,但我仍然有这个想法,谢谢:) – Shaokan

7

我一直在使用描述为here的通用资源库。我一直在使用作者的设计来处理我的代码,并且它工作得很好。下面是我一直使用的代码:

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

例如,要获得一个项目由它的ID。

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

将返回单个用户。或

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

实验与此库,看它是否符合您需求。

+0

我非常喜欢这种方式 – AndreMiranda