【问题标题】:Can I avoid a nested SQL query for a simple Linq to Entities projection?对于简单的 Linq to Entities 投影,我可以避免嵌套 SQL 查询吗?
【发布时间】:2014-10-31 16:20:31
【问题描述】:

给定一个简单的 Linq to EF (EF5) 语句:

MyDBSet.Select(x => x.Column1)

将生成以下 SQL:

SELECT
[c].[Column1] AS [Column1]
FROM (SELECT 
[MyDBSet].[Column1] AS [Column1],
[MyDBSet].[Column2] AS [Column2],
...
[MyDBSet].[ColumnN] AS [ColumnN]
FROM [dbo].[MyDBSet] as [MyDBSet]) as [c]

返回所有列的额外嵌套查询确实是不必要的。它可能是无害的,但我认为我在如何将其扩展到相当复杂的查询方面遇到了问题。那么:有没有办法让 EF 在没有这个额外的嵌套查询的情况下生成 SQL?我的 linq 语句是用表达式树生成的,所以我想避免使用任何传递 SQL。

【问题讨论】:

  • 您为什么需要这样做?优化代码不是查询提供者的工作。数据库在优化该查询时应该没有问题。
  • 将 DBContext API 中的惰性、急切和显式加载视为在 EF 中创建 SQL 查询的不同方式。
  • @Servy,您不能假设数据库会优化查询。我认为他想创建更复杂的查询。 SQL 是一种奇怪的生物 - 有时它会优化,而有时这种类型的小变化会影响性能。

标签: c# sql-server linq entity-framework


【解决方案1】:

奇怪。

我刚刚在LinqPad 的测试数据库中尝试了以下内容:

Contacts.Select(x => x.Email)

这是 SQL 输出:

SELECT [t0].[email]
FROM [contacts] AS [t0]

所以你是对的 - 你的上下文中的某些东西导致它选择所有列,然后为 column1 投影。似乎这个线程上的 OP 也有同样的问题,这个答案展示了一种优化方法:

https://stackoverflow.com/a/13258796/201648

这不是最干净的解决方案,但它肯定会让您对 SQL 进行更精细的控制。同一线程上的另一个答案提供了一些关于 EF 以这种方式运行的原因:

为什么实体框架会产生嵌套查询?简单的答案是 因为实体框架将您的查询表达式分解为 表达式树,然后使用该表达式树来构建您的 询问。树自然生成嵌套查询表达式(即 子节点生成查询,父节点生成查询 该查询)。

https://stackoverflow.com/a/13258313/201648

这是在黑暗中拍摄的,但是您是否尝试过使用 F10 和 F11 逐步遍历上下文调用的每个级别,以查看每个点生成的内容?我很好奇子查询是否在堆栈的早期生成,因为一些子选择在堆栈中并不明显更高。另外,MyDBSet.Select(x => x) 会生成什么?

【讨论】:

  • 谢谢-这很有用。我会深入研究这个,看看我发现了什么。 =)
【解决方案2】:

正如Chris Hermut 提到的,延迟加载您的查询:

IQueryable<ColumnType> query = context.MyDBSet.Select(X => X.Column1);

IEnumerable<ColumnType> result = query.ToList();

【讨论】:

  • 遗憾的是,使用惰性方法似乎并没有改变生成的 SQL。
  • linq 生成这样的 sql 查询
猜你喜欢
  • 2023-04-07
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多