在 Where LINQ 查询中使用 Contains()

Posted

技术标签:

【中文标题】在 Where LINQ 查询中使用 Contains()【英文标题】:Using Contains() in a Where LINQ query 【发布时间】:2013-01-22 05:51:19 【问题描述】:

我正在使用这段代码从表中获取所需的行列表:

_userObjectSet = EntityFrameWorkContext.CreateObjectSet<User>();
List<int> selectedUserIDs = Method(); //Returns a specific set of int user IDs...
var results = _userObjectSet.Where(c => selectedUserIDs.Contains(c.ID)).ToList();

这确实有效,因为“结果”将仅包含 ID 字段与 selectedUserIDs 列表中的元素匹配的记录。

问题是,如果我查看 Windows 任务管理器,LINQ 似乎会加载表的所有行,然后将它们过滤掉。这个表中有大量的行,很快进程的权重就超过了 1GB,我不太喜欢。

我也可以看出它正在这样做是因为它需要时间来完成。

有什么方法可以告诉 LINQ 生成如下所示的查询:

SELECT * FROM Users WHERE ID IN (34,55,66,77, etc.)

这只会返回我正在寻找的确切行并使用更少的内存?

谢谢!

【问题讨论】:

如果这是 linq-to-sql 应该发生的事情。您是否尝试通过将数据上下文的 Log 属性设置为调试窗口来记录生成的 SQL? selectedUserIDs 包含多少个 id? 这只是一个想法(因为这是 NHibernate 所期望的),但是您是否尝试过 _userObjecSet.Where(c =&gt; selectedUserIDs.Any(y =&gt; y == c.ID)).ToList(); 或类似的? (注意:可能不是 100% 正确) 表包含 800,000+ 行,List 仅包含 3000 左右。我肯定可以运行分析器。 @Francis 包含 3000 个项目的 SQL In 子句是很多......很多。当列表少于某些特定数量的项目时,查询提供程序可能只能创建In 子句。理想情况下,ID 值将位于数据库的另一个表中,而不是在代码中列出一个列表,您将执行Join。甚至可能值得将它们插入临时表,然后执行Join,即使 ID 是临时的。 @Francis ID List 是从另一个数据库查询生成的吗?是否可以将这些数据作为 IQueryable&lt;int&gt; 表示其他查询而不是项目列表? 【参考方案1】:

尝试加入..我想你可以找到不同之处...

List<int> selectedUserIDs = Method(); //Returns a specific set of int user IDs...
var results = (from u in _userObjectSet 
               join id in selectedUserIDs on u.Id equals id
               select u);

【讨论】:

【参考方案2】:

为此,您将需要 LinqKit 之类的东西。具体来说,请查看套件随附的 PredicateBuilder,因为我认为您需要它来解决您的问题。

【讨论】:

不确定这是否可行,考虑到List 的大小(3000 项)。 虽然是一个有用的链接,但我不确定这个答案有多大帮助,因为那里没有任何明显的东西可以真正解决这个问题。 我开始打字的时候没有注意到关于 3000 项的评论(这在平板电脑上有点慢)..

以上是关于在 Where LINQ 查询中使用 Contains()的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 Linq 查询:.Where 链 vs &&

Linq 中的 Groupby 和 where 子句

C#基础:LINQ 查询函数整理

LINQ to SQL查询中的C#Dynamic WHERE子句

LINQ中where操作符

概括 linq 查询中的 where 子句