使用 linq 过滤繁琐的对象列表

Posted

技术标签:

【中文标题】使用 linq 过滤繁琐的对象列表【英文标题】:filtering cumbersome list of objects with linq 【发布时间】:2022-01-06 01:03:04 【问题描述】:

我有一个繁琐的对象列表。计数约为 25.837。 一旦我想用这样的 linq 表达式过滤我的对象

        underManagementPersonList.OrderByDescending(x => x.BarCode).Where(x => x.CardNum.Contains("0480286000") || x.BarCode.Contains("0480286000") || x.PersonName.Contains("0480286000")).Skip(pageIndex).ToList();   Evaluation timed out    System.Collections.Generic.List<GTS.Clock.Model.MonthlyReport.UnderManagementPerson>

我收到此错误

评估超时

虽然没有这样的问题,但我得到 100 件物品的数量较少

underManagementPersonList.Take(100).OrderByDescending(x => x.BarCode).Where(x => x.CardNum.Contains("0480286000") || x.BarCode.Contains("0480286000") || x.PersonName.Contains("0480286000")).Skip(pageIndex).ToList();

【问题讨论】:

这是 LINQ 2 对象还是您使用数据库? 先过滤再排序。排序是代码中迄今为止最耗时的事情。不确定它是否能解决您的问题,但没有理由对您的收藏进行分类然后将它们全部扔掉。 @amirkian - 能否请您发布课程GTS.Clock.Model.MonthlyReport.UnderManagementPerson 以及确切的错误信息是什么? 这是由数据库支持的吗?看着它,我认为您需要对您的搜索词更加果断 - 0480286000 不是人名,您可能应该让条形码和卡号搜索等于,而不是包含。检查搜索词并运行有针对性的搜索:如果都是数字和 16 个字符;卡努姆。否则,如果全部为数字;条码。否则,人名 不知道什么后端数据库,但您可能会通过SELECT * FROM t WHERE a = @x OR b = @x OR c = @x 并使其成为SELECT * FROM t WHERE a = @x UNION SELECT * FROM t WHERE b = @x UNION SELECT * FROM t WHERE c = @x 得到一些改进 - 我知道,你会想象它们会是相同的,但过去使用 SQLServer 的经验是,在某些情况下,它只是不会将查询与 OR 并行化,而与 UNION 的区别很明显 【参考方案1】:

因为这只是一个对象列表,所以顺序很重要 - 您可以通过将 .Where() 放在 .OrderByDescending() 之前来加快处理速度

underManagementPersonList
    .Where(x => x.CardNum.Contains("0480286000")
        || x.BarCode.Contains("0480286000")
        || x.PersonName.Contains("0480286000"))
    .OrderByDescending(x => x.BarCode)
    .Skip(pageIndex)
    .ToList();

这仍然有潜在的昂贵/缓慢的字符串。包含对 25,837 个对象的多达 3 次调用,但至少您只会对与您的 Where 匹配的对象子集进行排序。

注意:在 OrderByDescending 之前放置 Where 将以相同的顺序生成相同的一组对象 - 不同之处在于,只要至少有一个对象被您的 where 过滤掉,那么它会更快 -与您的位置匹配的集合越小,orderby 的速度就越快。

【讨论】:

我仍然得到评估超时。 @amirkian - 那么您没有向我们展示的代码存在问题。请提供所有相关代码。 @Enigmativity 相关代码非常复杂,可以在这里分享。最终我最终用 sql 执行此操作并获得响应,然后我只有一条记录。 @amirkian - 解决你原来的问题还是不错的。

以上是关于使用 linq 过滤繁琐的对象列表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Linq 根据另一个列表过滤列表?

使用 LINQ 过滤列表

如何用对象列表过滤对象列表? [复制]

CSharp使用另一个列表及其嵌套列表过滤带有LINQ查询的列表

使用 LINQ 过滤列表

使用列表属性通过 LINQ 过滤 dbset