【发布时间】:2016-04-09 22:23:20
【问题描述】:
简化示例:我有一个带有FirstName、LastName 的表。我有兴趣检索全部称呼不超过 N 的人,按长度排序。为了实现这一点,我有这样的代码:
var result = await Context.People
.Select(p => new PersonWithSalutation
{
FirstName = p.FirstName,
LastName = p.FirstName,
FullSalutation = p.FirstName + " " + p.LastName
})
.Where(p => p.FullSalutation.Length < maxLength)
.OrderBy(p => p.FullSalutation)
.Take(maxResults)
.ToListAsync();
查询如下所示:
SELECT TOP (10)
[Project1].[C1] AS [C1],
[Project1].[Name] AS [Name],
[Project1].[Id] AS [Id],
[Project1].[C2] AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
1 AS [C1],
...calculated stuff... AS [C2]
FROM [dbo].[People] AS [Extent1]
WHERE ...exactly the same stuff... <= @p__linq__3
) AS [Project1]
ORDER BY [Project1].[C2] ASC
这可以解决问题并生成对数据库的单个查询。问题在于计算的投影,因为它在结果查询中出现了两次:一次在SELECT 中,然后在WHERE 子句中。这个例子被简化了,但在我的真实案例中,我正在做大量的数学运算,我希望只计算一次。正如您在上面看到的,C2 在 order 子句中被重用。我想对WHERE 子句做同样的事情,我认为这将涉及另一个子查询)。我将如何实现这一目标?
【问题讨论】:
-
我会假设 SQL Server 意识到计算是相同的,在这种情况下不会执行两次。你有理由相信它吗?
标签: sql-server performance entity-framework linq-to-entities projection