当前位置: 首页 > 面试题库 >

LINQ中StartsWith()不会转换为Like('abc%')

丁英韶
2023-03-14
问题内容

我有以下asp.net核心LINQ代码:

    List<UserSearchResult> results = await db.ApplicationUsers.Where(u => u.Name.StartsWith(name) && !u.Deleted && u.AppearInSearch)
                                    .OrderByDescending(u => u.Verified)
                                    .ThenBy(u => u.DateAdded) // Added to prevent duplication of results in different pages
                                    .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();

不幸的是,这转化为以下内容:

SELECT [t].[Name], [t].[Verified], [t].[PhotoURL], [t].[Id], [t].[Subdomain]  FROM (      SELECT [u0].*      FROM [AspNetUsers] AS [u0]      WHERE ((([u0].[Name] LIKE @__name_0 + N'%' AND (CHARINDEX(@__name_0, [u0].[Name]) = 1)) OR (@__name_0 = N'')) AND ([u0].[Deleted] = 0)) AND ([u0].[AppearInSearch] = 1)      ORDER BY [u0].[Verified] DESC, [u0].[DateAdded]      OFFSET @__p_1 ROWS FETCH NEXT @__p_2 ROWS ONLY  ) AS [t]

我不知道为什么会有这部分:

(CHARINDEX(@__name_0, [u0].[Name]) = 1)) OR (@__name_0 = N''))

不仅像

非常感谢


问题答案:

EF Core中SQL转换的规则尚不清楚,远未完善,尚在讨论中,并且随着每个次要发行版的发布而不断变化。

的翻译StartsWithEndsWithContains进行了讨论,并改了好几次-
例如,问题#474:查询:提高字符串的StartsWith,的endsWith的翻译和包含)。的翻译StartsWith已经在最新的官方版本V1.1.2甚至被改变,所以V1.1.1翻译

(CHARINDEX(@__name_0, [u0].[Name]) = 1)) OR (@__name_0 = N''))

现在将像

[u0].[Name] LIKE @__name_0 + '%' AND (CHARINDEX(@__name_0, [u0].[Name]) = 1)) OR (@__name_0 = N''))

这个想法是LIKE有条件的,允许查询优化器使用索引,然后像以前一样对第二个条件进行慢速过滤(这是关于正确处理(类似于C#)搜索字符串以及空搜索字符串中的通配符的全部内容)。

因此,您可以尝试升级,看看是否有帮助。即将发布的v2将为诸如db等特定于db的运算符提供更自然的支持LIKE

当前的另一个解决方法(如果以上确实是性能瓶颈)是直接使用SQL构建查询过滤部分,而使用LINQ直接构建其余部分(与EF6相反,EF Core允许这样做):

var results = await db.ApplicationUsers
    //.Where(u => u.Name.StartsWith(name) && !u.Deleted && u.AppearInSearch)
    .FromSql("select * from ApplicationUsers where Name like {0}", name + "%")
    .Where(!u.Deleted && u.AppearInSearch)
    .OrderByDescending(u => u.Verified)
    .ThenBy(u => u.DateAdded) // Added to prevent duplication of results in different pages
    .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();

请注意,该FromSql方法支持参数,因此不要担心SQL注入。仍然需要了解表名,列名和具体的数据库SQL语法-ORM应该为您抽象一些内容。



 类似资料:
  • 完整的蓝牙聊天服务类:https://github.com/frcteam1501/frcrecyerushpitscouter/blob/master/app/src/main/java/org/huntingtonrobotics/frcrecyerushpitscouter/bluetoothchat/bluetoothchatfragment.java 完整的蓝牙聊天片段类:https:/

  • 问题内容: 我有以下XML文件,我需要在服务器中将其转换为JSON。最初,我认为我会将其转换为Dictionary,然后使用JavaScriptSerializer将其转换为JSON,但由于每列可能具有不同的值类型,所以我认为它不会起作用。有人在C#/ LINQ中做过类似的事情吗? 我需要保留每列的值类型(布尔,字符串,整数)。 我会很高兴就此提出任何建议,因为我刚刚开始使用XML。谢谢。 问题答

  • 问题内容: 我有一些Objective-C的遗留代码,它声明了像 如此处所写https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html Swift自动将产生错误的Objective-C方法转换为根据Swift的本机错

  • 我使用下面的库转换我的html div到画布。 https://html2canvas.hertzen.com/ 事情按预期进行。现在,我想要的基本上不是下载(通过saveAsPNG()方法可以下载),而是将数据发送到服务器。现在我们知道,我们需要使用toDataUrl()将其转换为base64。 使用此方法toDataUrl(),表示不是函数。 下面是片段 1) 以画布形式提供输出 2)canv

  • 问题内容: 基本上,我想使用linq进行此SQL查询: 这是我想出的: 但 在 后 o.Identifier 无效。 关键字IN的正确语法是什么? 问题答案: 我有点晚了,但是我做了一个演示! 正如其他人所说,我始终使用Contains:

  • 问题内容: 我有一个在SQL中完美运行的查询,但是我有最糟糕的时间将其转换为linq。该表(下面的表1)保存了多种记录类型的状态更改。联接需要设置两个字段以创建有效联接:SubmissionId(状态所属的表的pk)和SubmissionTypeId(确定状态所属的表)。 我已经尝试过使用x.DefaultIfEmpty()中的y到x进行多次迭代,并且无法在正确的位置设置where子句。我需要从T