2012-02-14 117 views
8

我经常看到像这个例子库模式:Repository模式 - 方法太多

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllByName(string name); 
} 

但你如何处理的情况下,您可能需要做一个复杂的搜索?我不认为这会增加很多方法的接口,将使它最终看起来像一个好主意:

IEnumerable<T> GetAllByFirstName(string name); 
IEnumerable<T> GetAllByLastName(string name); 
IEnumerable<T> GetAllByFirstAndLastName(string name); 
IEnumerable<T> GetAllByAddress(string name); 
... 
... 
... 

回答

6

使用Predicate Builder动态地建立WHERE条件

public interface IRepository<T> 
{ 
    T GetById(int id); 

    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate); 
} 

然后建立条件

var predicate = PredicateBuilder.True<Customer>(); 
    if (!string.IsNullOrEmpty(FirstName)) 
    { 
     predicate = predicate.And(d => d.FirstName.Contains(FirstName)); 
    } 

    if (!string.IsNullOrEmpty(LastName)) 
    { 
     predicate = predicate.And(d => d.LastName.Contains(LastName)); 
    } 

    var products = productRepo.GetAllBy(predicate); 

创建一个类来通过搜索条件

public class CustomerFilterCriteria 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public string Address { get; set; } 

} 

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllBy(CustomerFilterCriteria criteria); 
} 
+1

什么如果我不能使用表达式?例如,如果我必须在存储库后面使用存储过程? – Books 2012-02-14 08:37:19

+0

@Ashley查看编辑答案 – Eranga 2012-02-14 08:44:48

+0

自这个答案发布以来,这些功能是否已经内置到linq中? – 2015-03-31 16:43:59

0

你可以添加一个filtermodel并检查哪个过滤器已装满像这样:

IEnumerable<T> GetAllByFiilter(FilterModel filter); 


public class FilterModel { 
    public string Lastname {get;set;} 
    public string Firstname {get;set;} 
} 


public IEnumerable<T> GetAllByFilter(FilterModel filter) { 
    if(!string.IsNullOrWhiteSpace(filter.Lastname) { 
    //add restriction 
    } 
    // .. etc .. 
} 
0

“获取方法”可能是它自己的接口:

public interface IGetMethod<T> 
    { 
     IEnumerable<T> get(String name); 
    } 

    class GetByName<T> : IGetMethod<T> 
    { 
     IEnumerable<T> get(String name) 
     { 
      // ... 
     } 
    } 

    public interface IRepository<T> 
    { 

     IEnumerable<T> GetAllByMethod(IGetMethod<T> method, string name); 
    } 
2

问:为什么把库通用的,如果你将要暴露类型的特定方法(或做你r实体有FirstName,LastName,Address等吗?)。

如果您的底层数据资源是启用了LINQ表达式树,那么通用签名也是通用的,例如,

IEnumerable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter) 

如果你想你的查询是 '堆叠',你可能会暴露一个IQueryable

IQueryable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter) 
1

继承人我提供我的仓库模式的方法,

public interface IRepository<T> : IDisposable 
    { 
     void Create(T entity); 

     void Delete(T entity); 

     void Update(T entity); 

     IQueryable<T> GetAll(); 

     T GetBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes); 
    } 

我个人认为,它能够更好地允许查询以后,因为有时候你需要它,我也喜欢有一个通用的getby。这样做的结合是我所有的类型化存储库一般都没有单独的实体配置。

阅读我关于在这里http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

0

有一个通用的存储库

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate); 
} 

则有更具体的资料库

public interface IUserRepository : IRepository<T> 
    { 
     User GetByName(string name); 
    } 

这样的通用仓库处理所有的CRUD的东西文章和您的实际存储库任何东西