gpt4 book ai didi

c# - 我可以使用什么构造来代替 Contains?

转载 作者:可可西里 更新时间:2023-11-01 03:05:59 26 4
gpt4 key购买 nike

我有一个包含 id 的列表:

var myList = new List<int>();

我想从 db 中选择 id 来自 myList 的所有对象:

var objList= myContext.MyObjects.Where(t => myList.Contains(t.Id)).ToList();

但是当 myList.Count > 8000 我得到一个错误:

The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

我认为这是因为我使用了 Contains()。我可以使用什么来代替 Contains?

最佳答案

您可以通过添加AsEnumerable() 在客户端执行查询“隐藏” Where Entity Framework 中的子句:

var objList = myContext
.MyObjects
.AsEnumerable()
.Where(t => myList.Contains(t.Id))
.ToList();

要提高性能,您可以将列表替换为 HashSet :

var myHashSet = new HashSet<int>(myList);

然后修改Where中的谓词因此:

  .Where(t => myHashSet.Contains(t.Id))

就实现时间而言,这是“简单”的解决方案。但是,由于查询在客户端运行,您的性能可能会很差,因为所有 MyObjects行在被过滤之前被拉到客户端。

你得到错误的原因是因为 Entity Framework 将你的查询转换成这样的东西:

SELECT ...
FROM ...
WHERE column IN (ID1, ID2, ... , ID8000)

所以基本上列表中的所有 8000 个 ID 都包含在生成的 SQL 中,这超出了 SQL Server 可以处理的限制。

生成此 SQL 的 Entity Framework “寻找”的是 ICollection<T>List<T> 实现和 HashSet<T>因此,如果您尝试将查询保留在服务器端,则使用 HashSet<T> 不会提高性能。 .然而,在客户端,情况就不同了ContainsO(1)对于 HashSet<T>O(N)对于 List<T> .

关于c# - 我可以使用什么构造来代替 Contains?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28166304/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com