RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1437883
Accepted
Vadim Tregubenko
Vadim Tregubenko
Asked:2022-08-10 01:57:52 +0000 UTC2022-08-10 01:57:52 +0000 UTC 2022-08-10 01:57:52 +0000 UTC

过滤和排序列表

  • 772

大家好。有一个 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

c# asp.net-core
  • 1 1 个回答
  • 64 Views

1 个回答

  • Voted
  1. Best Answer
    Alexander Petrov
    2022-08-10T03:12:33Z2022-08-10T03:12:33Z

    您的代码中没有过滤。
    事实证明,该方法GetAsync返回某个表中的所有数据。
    好的,假设为简洁起见省略了过滤。

    如果有的话,Select那就是投影。

    该方法.ToList();实现了请求。所有数据将从数据库中检索并存储在列表中。以下代码已经对该列表进行了排序。这是不对的!过滤和排序必须在数据库中完成!这几乎总是更快、更有效。


    您的任务可以使用不同的 EF 库来解决。其中包括 Dynamic LINQ - 它允许您将表达式参数设置为字符串,LinqKit - 它允许您使用 PredicateBuilder 动态组合查询。


    但是,您可以不使用其他库。对于您的情况,代码可能是最简单的。

    public async Task<IEnumerable<BlackList>> Handle<T>(
        Expression<Func<BlackList, T>> expression, Sort sort)
    {
        if (sort == Sort.Asc)
            return await _readonlyRepository.GetAsync()
                .OrderBy(expression)
                .ToListAsync();
        else
            return await _readonlyRepository.GetAsync()
                .OrderByDescending(expression)
                .ToListAsync();
    }
    

    这里假设该方法GetAsync返回IQueryable<BlackList>.
    为简洁起见,省略了 CancellationToken。

    我们将 Expression 作为参数传递。
    在代码中它看起来像这样:

    await Handle(blackList => blackList.LastName, Sort.Desc);
    

    也就是说,"LastNameDesc"我们传递的不是字符串,而是两个参数:一个带有要排序的属性的表达式,以及一个带有排序方向的枚举。

    我们从方法返回IEnumerable。可以做到List。谁会消耗这个方法的结果,谁都不在乎IOrderedEnumerable。


    枚举Sort看起来像这样:

    public enum Sort { Asc, Desc }
    

    如果你喜欢,你可以使用参数来代替bool isAscending。



    我记得EF.Property方法的存在,它把属性的名称当作一个字符串。有了它,代码可以实现如下:

    public async Task<List<BlackList>> Handle(string sortProperty, Sort sort)
    {
        if (sort == Sort.Asc)
            return await _readonlyRepository.GetAsync()
                .OrderBy(x => EF.Property<object>(x, sortProperty))
                .ToListAsync();
        else
            return await _readonlyRepository.GetAsync()
                .OrderByDescending(x => EF.Property<object>(x, sortProperty))
                .ToListAsync();
    }
    

    像这样调用:

    await Handle("LastName", Sort.Desc)
    

    或者,您可以去掉第二个参数并将排序方向与名称一起传递,就像在您的原始版本中一样:

    public async Task<List<BlackList>> Handle(string sortProperty)
    {
        if (sortProperty.EndsWith("Desc"))
        {
            sortProperty = sortProperty[..^4];
            return await _readonlyRepository.GetAsync()
                .OrderByDescending(x => EF.Property<object>(x, sortProperty))
                .ToListAsync();
        }
        else
            return await _readonlyRepository.GetAsync()
                .OrderBy(x => EF.Property<object>(x, sortProperty))
                .ToListAsync();
    }
    

    称呼:

    await Handle("LastNameDesc")
    
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5