在 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 => selectedUserIDs.Any(y => y == c.ID)).ToList();
或类似的? (注意:可能不是 100% 正确)
表包含 800,000+ 行,List 仅包含 3000 左右。我肯定可以运行分析器。
@Francis 包含 3000 个项目的 SQL In
子句是很多......很多。当列表少于某些特定数量的项目时,查询提供程序可能只能创建In
子句。理想情况下,ID 值将位于数据库的另一个表中,而不是在代码中列出一个列表,您将执行Join
。甚至可能值得将它们插入临时表,然后执行Join
,即使 ID 是临时的。
@Francis ID List
是从另一个数据库查询生成的吗?是否可以将这些数据作为 IQueryable<int>
表示其他查询而不是项目列表?
【参考方案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()的主要内容,如果未能解决你的问题,请参考以下文章