排序,存储库模式中的分页和松散耦合

Sorting, Paging in the Repository pattern & loosely coupled

提问人:MiniW 提问时间:7/14/2016 最后编辑:MiniW 更新时间:1/2/2017 访问量:1976

问:

我有一个简单地列出我数据库中所有销售人员的。 我想在网格中显示结果(想象一个 Web 界面),以便用户可以显示或隐藏任何字段、对列进行排序以及使用分页。SalesmanRepository

假设我有一个非常大的集合,因此排序和分页必须是服务器端的。

我的问题是,我怎样才能在我的架构中保持松散耦合?

  1. 我不希望我的数据库列的名称绑定到 UI 的列。我希望以后能够灵活地更改新类型的数据库。
  2. 我应该如何处理分页?例如,通过直接向存储库的方法添加参数(例如 and)?pagenumberOfItemsPerPage
  3. 我应该如何进行排序?我不想将数据库列的名称绑定到排序参数,因为我可以拥有一种新型数据库,并且会破坏我所有的软件。

基本上,我怎样才能接近这些概念并保持松散耦合?理想情况下,我想要一种与语言无关的方法,但如果有更好的特定于语言的答案,我会使用。C#


编辑:我的问题可以更精确:我怎样才能告诉我的存储库按字段排序,而不直接提及字段的名称?


编辑 2:我想告诉我的存储库按字段排序,但我不想绑定到实现,因为我的存储库的接口在我的业务逻辑层(或域层)中。

假设我有一个MySQL数据库(因此是一个),其中有一个名为包含列的表。SalesmanMySQLRepositorySalesmanName

现在假设我还有一个 SQL Server 数据库(带有 ),其中包含一个名为包含相同列的表,但在这里我会命名它,因为我的团队出于某种原因决定在列中使用某种前缀。它是特定于细节的,与业务逻辑无关。SalesmanSQLRepositorySalesmanNameBobbyName

我应该是什么样子的?我不想直接发送字符串,因为每个实现都是完全不同的。我想会有这样的方法,但是我应该如何处理这个参数?SalesmanRepositoryPagedResult<Salesman> List(SortingParameter field)

C# 设计模式 体系结构 与语言无关 的存储库

评论

0赞 Chih-Ho Andy Chou 7/14/2016
听起来您正在数据模型和视图之间的 ViewModel 中寻找另一个抽象?
0赞 MiniW 7/14/2016
您能指导我 ViewModel 如何帮助我完成排序和分页吗?
0赞 warrior 7/14/2016
对于小型数据集,您不必担心 pageSzie 或任何其他过滤器或存储库中的排序,而是控制器(MVC 模式)应该处理分页、排序或过滤。如果是大型数据集,我会使用 OData (asp.net/web-api/overview/odata-support-in-aspnet-web-api),将数据公开为服务
0赞 dbugger 7/14/2016
任何系统怎么知道要排序什么,如果你不告诉它--在某个时候--要排序什么?
0赞 MiniW 7/15/2016
我不太确定。我发现的一个解决方案是声明一个枚举,其中包含可用于排序的字段。我不知道是否也有某种策略模式或其他什么,我正在寻找替代方案。

答:

0赞 guijob 7/14/2016 #1

我做过一次。我通过创建一个对象解决了这个问题,如下所示:

public class ClientPage
{
    private int PageIndex;
    private int PageLengh;
    private List<Client> Clients;
    private int ClientsCount;
}

因此,我可以管理页面而不是客户列表。

希望这能以某种方式帮助你。

评论

0赞 MiniW 7/14/2016
我明白,我可以有一个.但是现在,我仍然需要解决我的排序问题。PagedResult<E>
0赞 guijob 7/14/2016
我不明白你的排序问题。您是只想要一种排序算法,还是想要一种从数据库带来的所有排序集的分页方法?我会假设第二选择。为此,我建议您将所有排序的数据存储在服务器内存中,以便您可以将部分发送到客户端。PageIndex 和 PageLenght 就是为此目的。例如,如果您的列表有 10 个数据,而您和 3 x 3 发送,您应该开始发送索引 1 长度为 3 的客户端页面,其中包含三个第一个数据,然后第二个页面的索引为 4 长度为 3,依此类推......希望这会有所帮助
0赞 MiniW 7/14/2016
假设我有一百万个条目。如果我想按字段“Name”对第 1 页的前 n 个条目进行排序(例如),我无法获取前 n 个条目然后对客户端进行排序,因为它只会对获取的条目进行排序。我需要在服务器端对它们进行排序。话虽如此,我知道我数据库中的列名也被命名为“Name”,但我想找到一种方法来保持松散耦合。我不希望我的业务逻辑通过我的存储库发送字符串“Name”,并直接在我的实现中使用该字符串。我正在寻找一个松散耦合的解决方案。
0赞 Locke Duan 7/14/2016 #2

似乎您不希望在客户端和数据库上进行分页和排序,因此,我认为您唯一可以进行分页和排序的地方是在内存中,因此您可以编写一个共享方法,例如

public static IEnumerable<T> SortingAndPaging<T>(IEnumerable<T> entities, int pageSize, int pageNum, string sortField, string order)
{       
   //your sorting and paging logic goes here, maybe Linq is helpful here
}

通过这种方式,我们可以实现与数据库无关

0赞 Daniel Lee 1/2/2017 #3

我会通过将列标题中的文本作为我想要排序的文本发送到后端来解决,然后使用反射在对象中查找该属性名称。您需要确保列中的显示名称可通过算法或查找转换为字段名称。下面的代码是伪的,但方法是可靠的。

前端:

<th class="sortable">Last Name</th> ...
$('.sortable').onClick(function(event){
      //send request to backend with text of header as sortBy
      ...
 });

后端:

List<Person> GetPeople ( string sortBy )
{
     //Person has property lastName
     var propery = Person.GetField(SortByStringToPropertyName(sortBy));
     List<Person> people = db.Persons.OrderBy(property).ToList();
     return people;
}