我经常看到示例存储库模式,如下所示:
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);
...
...
...
答案 0 :(得分: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 :(得分:2)
问题:如果您要公开特定于类型的方法(或者您的所有实体是否具有FirstName,LastName,Address等?),为什么要使存储库具有通用性?
如果您的基础数据资源启用了LINQ表达式树,则公共签名也是通用的,例如
IEnumerable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)
如果您希望查询“可堆叠”,则可以公开IQueryable
IQueryable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter)
答案 2 :(得分: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
答案 3 :(得分: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 ..
}
答案 4 :(得分:0)
“get method”可以是它自己的接口:
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);
}
答案 5 :(得分: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内容和你的实际存储库