2011-06-25 66 views
8

Tôi đang tìm kiếm giờ và tôi đã đọc một số bài viết về cách xây dựng kho lưu trữ chung (GR). Theo như tôi đã hiểu, GR được sử dụng trong trường hợp các mã tương tự có mặt. Ví dụ: để tìm nạp một hàng từ bảng theo id của nó hoặc toàn bộ bảng. Tuy nhiên, vẫn còn, tôi không thể hiểu làm thế nào để nhận ra điều này.Kho lưu trữ chung của 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) 
    } 
} 

Sau đó, tôi muốn làm một cái gì đó tương tự:

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

Hãy ai cũng có thể giải thích cho tôi làm thế nào để hoàn thành nhiệm vụ này?

Trả lời

8

Đây chỉ là mã giả để tạo kho lưu trữ chung chung được nhập mạnh mẽ.

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

Sau đó, bạn có thể tạo một giao diện kho lưu trữ cụ thể nói

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

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

Không biết nếu điều này là những gì bạn đang tìm kiếm. Điều này là nếu bạn đang sử dụng EF.

+0

Tôi đang sử dụng L2SQL nhưng tôi vẫn có ý tưởng, cảm ơn :) – Shaokan

7

Tôi đã sử dụng kho lưu trữ chung như được mô tả here. Tôi đã sử dụng thiết kế của tác giả cho mã của tôi, và nó hoạt động rất tốt. Dưới đây là đoạn code tôi đã sử dụng:

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

Ví dụ, để có được một mục bởi nó là ID.

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

Sẽ trả lại một người dùng. Hoặc

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

Thử nghiệm với kho lưu trữ này, xem có phù hợp với nhu cầu của bạn hay không.

+0

Tôi thích cách này rất nhiều – AndreMiranda

Các vấn đề liên quan