使用 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 过滤繁琐的对象列表的主要内容,如果未能解决你的问题,请参考以下文章