使用 OrderBy 动态排序


  在使用客户端 Grid 等表格控件时,单击列头进行排序是很常见的事,因此你的查询里不可能再使用固定 OrderBy 或 OrderByDescending 了。

  Fireasy 提供了一个 OrderBy 扩展,通过定义一个 SortDifition 对象,进行动态排序。SortDifition 对象的 Member 表示使用排序的字段,一般由界面端传入,Order 表示升序或降序。

[TestMethod]
public void TestOrderByExtend()
{
    using (var db = new DbContext())
    {
        var sorting = new SortDefinition();
        sorting.Member = "OrderDate";
        sorting.Order = SortOrder.Descending;

        var list = db.Orders
            .Select(s => new { s.OrderDate, CompanyName = s.Customers.CompanyName })
            .OrderBy(sorting)
            .ToList();
    }
}

  以上的代码手动设置使用 OrderDate 降序排序,但有时客户端并没有指定排序的字段,这个时候你需要指定一种默认的排序方式了。如下面的代码,当sorting 为 null 或未指定 Member 时,采用后面的 lambda 表达式进行排序。

[TestMethod]
public void TestOrderByExtendDefault()
{
    using (var db = new DbContext())
    {
        var sorting = new SortDefinition();
        //sorting.Member = "OrderDate";
        //sorting.Order = SortOrder.Descending;

        var list = db.Orders
            .Select(s => new { s.OrderDate, CompanyName = s.Customers.CompanyName })
            .OrderBy(sorting, u => u.OrderByDescending(s => s.OrderDate))
            .ToList();
    }
}

  如果你使用 Extend或 ExtendAs 返回对象时,扩展的属性与数据库字段不能一一对应时,客户端的排序需要将 Member 做映射替换处理。如下,ReorderLevelName 是一个扩展的属性,它返回的是枚举 ReorderLevel 的说明文本,当使用扩展属性 ReorderLevelName 排序时,应将其转换为使用 ReorderLevel 来进行排序。

[TestMethod]
public void TestOrderByExtendReplace()
{
    using (var db = new DbContext())
    {
        var sorting = new SortDefinition();
        sorting.Member = "ReorderLevelName";
        sorting.Replace("ReorderLevelName", "Products.ReorderLevel");

        var list = db.OrderDetails
            .Select(s => s.ExtendAs<OrderDetails>(() => new OrderDetails
                {
                    ReorderLevelName = s.Products.ReorderLevel.GetDescription(),
                }))
            .OrderBy(sorting)
            .ToList();
    }
}

💡 小提示

  • 替换时,如果使用了关联实体属性,则可以使用.的方式深入查找对应的属性。

  • Replace 方法指定一个数组,可以对不同的属性进行替换,字符串是成对出现的。