2011-06-25 142 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