【问题标题】:Perform SELECT statement on another SELECT using LINQ使用 LINQ 对另一个 SELECT 执行 SELECT 语句
【发布时间】: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


【解决方案1】:

首先构建内部选择:

var s1 = from u in db.AspNetUsers
          select new UserSearchResult
          {
              Name = u.Name,
              Verified = u.Verified,
              PhotoURL = u.PhotoURL,
              UserID = u.Id,
              Subdomain = u.Subdomain
         };

然后在外部选择中使用它:

 return  await (from u1 in s1 
                where u.Name.Contains(name) && !u.Deleted && u.AppearInSearch
                orderby u.Verified
                select u1)
                 .Skip(page * recordsInPage)
                 .Take(recordsInPage);

【讨论】:

  • 非常感谢。我应该在第一个选择中执行 where !u.Deleted & u.AppearInSearch 吗?因为我认为外部选择不会在内部选择中找到它们。谢谢。
  • 我实现了如下方式,发现问题:stackoverflow.com/questions/44333703/…谢谢
【解决方案2】:

当你做出选择查询.ToList()的输出时,输出又是一个列表。在此列表中,您可以申请另一个 .Select()。因此,与您之前的查询一样,您可以这样做:

 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
                                })
                                .ToList()
                                .Select(<your new query>)
                                .ToListAsync();

【讨论】:

  • 这个答案是关于结果的后处理,所以它与问题无关,这是关于 LINQ 代码被翻译成的 SQL 查询。
  • @JustAndrei 事实上,我正在寻找与第二个 SQL 查询匹配的 LINQ
猜你喜欢
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
相关资源
最近更新 更多