我正在编写一种方法,我希望能够根据订单中是否包含一个或多个订购产品来过滤订单,这些产品存在于用户选择的产品中。目前我正在这样做:
SelectedProductIDs.Intersect(orderProductIDs).Any()
在每个订单上执行(数据库中总共约有 20,000 个订单,预计会快速增长),其中 SelectedProducts 和 orderProductIDs 都是字符串 []。我还尝试对 SelectedProductID 和 orderProductID 使用预先生成的 HashSet,但这对比较速度没有明显影响。
但是,这两个都非常慢 - 每次选择更改大约 300 毫秒 - 特别是考虑到 UI 中 slider 可用的日期完全取决于此查询的结果,因此用户交互必须以某种方式停止.有没有(非常)明显更快的方法来做到这一点?
编辑:可能不够清楚 - 订单对象在启动时从 SQL 数据具体化,这些查询稍后在整个应用程序的辅助窗口中执行。 SQL与这个问题的细节无关;这是一个 LINQ-to-Objects 问题。
最佳答案
无论您做什么,LINQ intersect 都会根据输入值重建一个新的 HashSet
,即使输入已经是一个 HashSet
。它的实现会在内部改变哈希集(这是它避免产生重复值的方式),因此复制输入序列很重要,即使它已经是一个 HashSet
。
您可以创建自己的 Intersect
方法来接受哈希集,而不是填充新的哈希集。为了避免改变它,你必须满足于基于包的Intersect
,而不是基于集合的Intersect
(即,序列中的重复项将全部产生).显然,这对您来说不是问题:
public static IEnumerable<T> IntersectAll<T>(
this HashSet<T> set, IEnumerable<T> sequence)
{
foreach (var item in sequence)
if (set.Contains(item))
yield return item;
}
现在你可以写:
SelectedProductIDs.InsersectAll(orderProductIDs).Any();
并且哈希集不需要每次都重新构造。
关于c# - 检查两个可枚举之间是否存在共同的单个元素的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23156459/