Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在存储库模式中,分页、排序和搜索在哪里?_C#_Repository Pattern - Fatal编程技术网

C# 在存储库模式中,分页、排序和搜索在哪里?

C# 在存储库模式中,分页、排序和搜索在哪里?,c#,repository-pattern,C#,Repository Pattern,我有一个存储库类。我想在这个类中添加分页、搜索和排序。我怎么做 public class Repository<T> : IRepository<T> where T : class { private readonly DatabaseContext _context = new DatabaseContext(); public IQueryable<T> GetAll(params Expression<

我有一个存储库类。我想在这个类中添加分页、搜索和排序。我怎么做

 public class Repository<T> : IRepository<T> where T : class
    {
        private readonly DatabaseContext _context = new DatabaseContext();

        public IQueryable<T> GetAll(params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> dbQuery = _context.Set<T>();
            dbQuery = includeProperties.Aggregate(dbQuery, (current, includeProperty) => current.Include(includeProperty));
            return dbQuery.AsNoTracking().AsQueryable();
        }
}
公共类存储库:IRepository,其中T:class
{
私有只读DatabaseContext _context=新DatabaseContext();
公共IQueryable GetAll(参数表达式[]includeProperties)
{
IQueryable dbQuery=\u context.Set();
dbQuery=includeProperty.Aggregate(dbQuery,(current,includeProperty)=>current.Include(includeProperty));
返回dbQuery.AsNoTracking().AsQueryable();
}
}
与问题直接相关的自以为是的回答 对于.NET和存储库模式,通常尝试让您的方法返回
IQueryable
。这使您能够“链接”linq查询,然后可以将分页和排序等常见表达式链接到该查询。这意味着您可以越来越多地重复使用这些方法,并停止编写将使用一次或两次的大量自定义方法。这种情况的例外情况(总是存在异常,对吗?)是当您需要达到某些特定的性能指标时(例如,此代码需要快速运行,因此DB查询需要快速/特定)

在上面的代码示例中,您已经开始这样做:

public IQueryable<T> GetAll(params Expression<Func<T, object>>[] includeProperties) { .. }
public IQueryable GetAll(参数表达式[]includeProperties){..}
这使您能够将
GetAll
方法用于各种其他用途。寻呼?当然点菜?好啊我们也来点菜吧。实际上,您可以使用IQueryable中的所有普通linq扩展,并且根据所使用的底层存储库,可以适当地过滤结果

通常这意味着您的方法将最终执行数据库调用,然后结果将由链式方法进一步操作,但这同样取决于
GetAll
方法内部的实现

因此,总之->在存储库模式方法中执行分页/排序/聚合作为一般规则,因为这将导致更高的重用率和更少的特定硬编码方法

另一方面,如果要获得特定的性能相关指标,则应该有特定的方法,包括排序或分页。例如,您可能希望查询特定的存储过程或自定义Sql查询或自定义DocumentDB索引(是的,存储库模式可用于关系数据库之外的其他存储库,如Microsoft Sql Server。它可用于DocDb甚至文件系统!)

关于.NET+EF+存储库模式的固执己见的回答 请不要在此处使用存储库模式。正如OP中的一些评论所述,如果您使用的是EF,那么这实际上是一个存储库模式和一个已经完成的工作单元。在过去,人们在EF上添加了自己的存储库模式,因为在旧时代(tm)EF的失败。。主要涉及单元测试/集成测试

我们都向前走了。英孚(据说)已经成熟了。你现在真的不需要这么做

哦,您之所以使用存储库模式,是因为“您将来可能会切换数据库”的可能性通常为99%。人们很少更换DB,如果他们最终这样做。。。他们通常会遇到比希望使用存储库模式更多的问题

最后,是的,在某些场景中,存储库模式是有利的,但IMO没有说明可能会暗示这种情况,所以我假设不是这样。提示:像离线移动设备这样的应用程序,每个移动应用程序操作系统可能使用不同的DB。。。。也许

最后说明
这个完整的答案几乎可以作为观点来讨论。当使用Repository模式+.NET时,有一些一般性的建议(即我的前半部分答案),但我们总是在答案的后半部分陈述意见。所以祝你好运

我将提出一些与这里已有的答案和评论不同的建议。与其拥有一个通用的存储库,在那里您试图填充所有数据访问的用例,不如创建不同的存储库,其设计由您的域的需求驱动

在我看来,通用存储库带来的问题比它解决的问题还多:

  • 如果一个实体不需要删除功能怎么办
  • 如果一个实体不需要
    GetAll
    方法怎么办
  • IQueryable
    是一个有漏洞的抽象
通用存储库只会使您的设计更难发展,因为无论实际需求是什么,您最终都必须在任何给定情况下实现所有这些方法,并且人们仍然可以严重依赖返回的
IQueryable
,从而导致层间查询逻辑

相反,您可以轻松地执行以下操作:

public interface ICustomerRepository
{
    Customer Get(string id);
}

一旦您有了一些这样的存储库,创建其他存储库的成本就会大大降低。特别是如果您使用和利用类似的方法来实现这一点,那么实现易于创建、测试和使用的有重点的表达性存储库就变得轻而易举了。

不相关,但是:如果您接受
表达
并返回
IQueryable
,您将不会获得任何存储库模式。存储库模式应该抽象数据库访问,但使用表达式和queryable,您正在将数据库实现详细信息泄漏回域逻辑。分页:添加参数,告诉要跳过多少记录,顺序:添加参数,告诉属性要使用和方向,搜索:添加参数来描述要搜索的值。实体框架已经是一种存储库模式,您也可以自然地使用Skip和Take。我不确定这些天是谁在推广EF的这种模式,但在你走得太远之前,我会认真查看利弊。我