【发布时间】:2017-06-02 10:25:22
【问题描述】:
在我的 .NET Core 应用程序中,我在 LINQ 中有以下内容:
return await db.ApplicationUsers.Where(u=>u.Name.Contains(name) && !u.Deleted && u.AppearInSearch)
.OrderByDescending(u => u.Verified)
.Skip(page * recordsInPage)
.Take(recordsInPage)
.Select(u => new UserSearchResult()
{
Name = u.Name,
Verified = u.Verified,
PhotoURL = u.PhotoURL,
UserID = u.Id,
Subdomain = u.Subdomain
}).ToListAsync();
转换为以下 SQL:
SELECT [t].[Name], [t].[Verified],
[t].[PhotoURL], [t].[Id],
[t].[Subdomain]
FROM
(SELECT [u0].*
FROM [AspNetUsers] AS [u0]
WHERE (((CHARINDEX('khaled', [u0].[Name]) > 0) OR ('khaled' = N''))
AND ([u0].[Deleted] = 0))
AND ([u0].[AppearInSearch] = 1)
ORDER BY [u0].[Verified] DESC
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY ) AS [t]
但由于性能问题,Microsoft 支持建议我只查询固定长度的列(不是 varchar(max))。我被要求将 SQL 查询更改为:
SELECT [t].[Name], [t].[Verified],
[t].[PhotoURL] , [t].[Id], [t].[Subdomain]
FROM
(Select u0.Name, u0.Verified, u0.PhotoURL, u0.id, u0.Subdomain,
u0.Deleted, u0.AppearInSearch FROM [AspNetUsers] ) As [u0]
WHERE (((CHARINDEX('khaled', [u0].[Name]) > 0) OR ('khaled' = N''))
AND ([u0].[Deleted] = 0))
AND ([u0].[AppearInSearch] = 1)
ORDER BY [u0].[Verified] DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY ) AS [t]
这是另一个 SELECT 上的 SELECT。不幸的是,我不知道如何在 LINQ 中做到这一点。有人可以指导我如何在 LINQ 中进行第二个 SQL 查询吗?
谢谢
【问题讨论】:
-
首先,我会在分析器中检查两个查询的执行计划。我怀疑有什么不同。
-
这两个 sql 查询有什么区别?第一个是在另一个选择上选择,第二个是相同的。
-
我注意到的唯一区别是子选择中的 * 被替换为严格的列列表。我很确定这对 SQL 服务器查询执行计划完全没有影响。
-
我同意@JustAndrei。如果第二个查询比另一个查询更快/更有效,我会感到非常惊讶。无论如何,查询优化器都会自动将前者视为后者。
-
@JustAndrei 我需要将 SQL 查询转换为 LINQ。可以的话请指教。
标签: c# sql linq linq-to-sql asp.net-core