【问题标题】:When does this LINQ query go to the database?此 LINQ 查询何时进入数据库?
【发布时间】:2011-10-29 21:39:29
【问题描述】:

我担心这个 LINQ 调用实际上会两次访问数据库(一次用于 Contains,一次用于 ToList),而我真正想要的是嵌套 select 语句的 SQL 等效项:

var query1 = from y in e.cities where y.zip=12345 select y.Id;
var query2 = from x in e.users where query1.Contains(x.cityId) select x;
List<users> result = query2.ToList();

重点:如果这是两次访问数据库,我该如何避免呢?我怎样才能有一个像这样的嵌套选择语句,它一次只作为一个查询执行? Query1 只会返回 1 或 0 行。一定有比使用“包含”更好的方法。

【问题讨论】:

  • 简单的方法:观察连接。如果是 LINQ-to-SQL,则 hook ctx.Log = ...,或者 SQL profiler 工作,或者 mvc-mini-profiler 等

标签: c# sql linq select ado.net


【解决方案1】:

由于query1query2 都是IQueryable,因此只有一次访问数据库 - 当您调用query2.ToList()

您可以使用连接来组合查询,因为您正在查找相关信息并且关系是用户的城市 ID 与您限制的城市相同:

var result = (from x in e.users 
                join y in e.cities
                on x.cityId equals y.Id
                where y.zip == 12345
                select x.Id).ToList();

上面应该给你一个用户 ID 列表,这些用户(大概)居住在邮政编码 12345 中。

【讨论】:

  • 抱歉,已更改。所以你说“包含”实际上并没有访问数据库?难道不需要为了定义 query2 吗?
  • 你在骂我所有的错别字!再一次,对不起。 ID => 城市ID
  • @CarlBenson:在我的回答中已修复
  • 我想从技术上讲,你总是可以使用 Joins 而不是只返回一行的嵌套 Select 语句。有什么理由不这样做?
  • @CarlBenson:可能是您在多个其他查询中使用相同的子查询,因此您可以将其分解以保持您的代码库更小,在大多数其他情况下,我认为我更喜欢加入 - 它更具可读性。在您的特定情况下,它也应该具有更高的性能(虽然不是 100% 肯定,因为 Linq 已经优化,所以它取决于生成的 SQL)。此外,城市部分返回零、一或多行也无关紧要。
猜你喜欢
  • 2013-02-17
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多