大家好。有一个 Handler 将对象列表返回到前面。(Web API 项目)处理程序有 2 个调用它的控制器,一个用于搜索和排序,另一个仅用于排序。
尊敬的专家,请注意以下问题:如何搜索数组是否已通过 OrderBy 排序并相应地具有 IOrderedEnumerable 类型
返回类型最初是 List<> ,但必须更改为 IOrderedEnumerable<> 。
在这种情况下如何解决问题?
我有 4 个搜索条件。(前面有 4 个搜索字段,因为这是一个表格)
检查是否存在搜索请求。并从这里开始跳舞?那些。如果搜索失败,则只需默认(按日期)对列表进行排序并返回到前面。如果请求附带搜索字符串,则进行切换,在切换分支中,首先搜索列表,当它仍然是列表时,如果需要,然后在此分支中排序。
或者也许有一些 IOrderedEnumerable 的搜索方法?
目前的代码是:
readonly IReadonlyRepository<BlackListEntity> _readonlyRepository;
public GetBlackListQueryHandler(
IReadonlyRepository<BlackListEntity> readonlyRepository)
{
_readonlyRepository = readonlyRepository;
}
public async Task<IOrderedEnumerable<BlackList>> Handle(GetBlackListRequest request, CancellationToken cancellationToken)
{
IOrderedEnumerable<BlackList> x = null;
var result = await _readonlyRepository.GetAsync(cancellationToken);
var dataForSort = result.Value.Select(x => new BlackList
{
ItemId = x.Id,
...
}).ToList();
switch (request.SortBy)
{
case "LastName":
x = dataForSort.OrderBy(x => x.LastName);
break;
case "LastNameDecs":
x = dataForSort.OrderByDescending(x => x.LastName);
break;
case "FirstName":
x = dataForSort.OrderBy(x => x.FirstName);
break;
case "FirstNameDesc":
x = dataForSort.OrderByDescending(x => x.FirstName);
break;
case "MiddleName":
x = dataForSort.OrderBy(x => x.MiddleName);
break;
case "MiddleNameDesc":
x = dataForSort.OrderByDescending(x => x.MiddleName);
break;
case "PhoneNumber":
x = dataForSort.OrderBy(x => x.PhoneNumber);
break;
case "PhoneNumberDesc":
x = dataForSort.OrderByDescending(x => x.PhoneNumber);
break;
case "CreateDate":
x = dataForSort.OrderBy(x => x.CreateDate);
break;
case "CreateDateDesc":
x = dataForSort.OrderByDescending(x => x.CreateDate);
break;
}
return x;
仍然可以以某种方式简化过滤吗?否则带有开关和每个过滤脚本的设计似乎有点hacky
您的代码中没有过滤。
事实证明,该方法
GetAsync
返回某个表中的所有数据。好的,假设为简洁起见省略了过滤。
如果有的话,
Select
那就是投影。该方法
.ToList();
实现了请求。所有数据将从数据库中检索并存储在列表中。以下代码已经对该列表进行了排序。这是不对的!过滤和排序必须在数据库中完成!这几乎总是更快、更有效。您的任务可以使用不同的 EF 库来解决。其中包括 Dynamic LINQ - 它允许您将表达式参数设置为字符串,LinqKit - 它允许您使用 PredicateBuilder 动态组合查询。
但是,您可以不使用其他库。对于您的情况,代码可能是最简单的。
这里假设该方法
GetAsync
返回IQueryable<BlackList>
.为简洁起见,省略了 CancellationToken。
我们将 Expression 作为参数传递。
在代码中它看起来像这样:
也就是说,
"LastNameDesc"
我们传递的不是字符串,而是两个参数:一个带有要排序的属性的表达式,以及一个带有排序方向的枚举。我们从方法返回
IEnumerable
。可以做到List
。谁会消耗这个方法的结果,谁都不在乎IOrderedEnumerable
。枚举
Sort
看起来像这样:如果你喜欢,你可以使用参数来代替
bool isAscending
。我记得EF.Property方法的存在,它把属性的名称当作一个字符串。有了它,代码可以实现如下:
像这样调用:
或者,您可以去掉第二个参数并将排序方向与名称一起传递,就像在您的原始版本中一样:
称呼: