不区分大小写字符串比较LINQ到SQL

问题描述 投票:132回答:9

我读过,这是不明智的使用ToUpper的和tolower执行不区分大小写字符串比较,但我看不出有什么替代方案,当涉及到LINQ到SQL。 String.Compare的IGNORECASE和CompareOptions参数通过LINQ到SQL忽略(如果您使用的是区分大小写的数据库,你即使你问一个不区分大小写的比较区分大小写的比较)。是ToLower将或ToUpper的这里最好的选择吗?这个比那个好吗?我想我读的地方,ToUpper的比较好,但我不知道这是否适用于这里。 (我做了很多的代码审查和每个人都使用ToLower将)。

Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0

这相当于一个SQL查询,简单地用“测试”比较row.Name并且不会返回“测试”和“TEST”区分大小写的数据库上。

.net sql vb.net linq linq-to-sql
9个回答
109
投票

正如你所说的,还有toupper和ToLower将一些重要的不同,只有一个,当你试图做不区分大小写平等的检查是可靠准确。

理想的情况下,做一个不区分大小写的平等检查最好的办法是:

String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)

但请注意,这并不在这种情况下工作!因此,我们坚持与ToUpperToLower

注意OrdinalIgnoreCase,使其安全保护。但究竟该(在)案件类型,你使用敏感支票取决于你的目的是什么。但在一般使用的Equals平等检查,当你排序比较,然后选择合适的StringComparison作业。

迈克尔·卡普兰(文化和字符处理像这样一个公认的权威)具有与ToLower将在ToUpper的相关文章:

他说,“String.ToUpper - 使用ToUpper的,而不是ToLower将,并且为了拾起OS外壳规则指定InvariantCulture的”


71
投票

我在查询中使用System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test")

这执行了区分大小写的比较。


6
投票

我想这使用Lambda表达式,和它的工作。

List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );


0
投票

如果你传递一个字符串,它是不区分大小写到LINQ到SQL它会被传递到SQL不变,比较将在数据库中发生。如果你想要做的不区分大小写字符串比较数据库中的所有你需要做的就是创建一个lambda表达式,做的比较和LINQ到SQL供应商将是表达式转换成与你的字符串完整的SQL查询。

例如,这LINQ查询:

from user in Users
where user.Email == "[email protected]"
select user

被转换到由LINQ到SQL提供的SQL语句:

SELECT [t0].[Email]
FROM [User] AS [t0]
WHERE [t0].[Email] = @p0
-- note that "@p0" is defined as nvarchar(11)
-- and is passed my value of "[email protected]"

正如你所看到的,字符串参数将在SQL进行比较,这意味着事情应该工作只是你期望的方式来。


0
投票

为了执行大小写敏感LINQ到SQL查询声明“字串”字段是情况下,通过使用以下中的一个指定服务器数据类型敏感;

varchar(4000) COLLATE SQL_Latin1_General_CP1_CS_AS 

要么

nvarchar(Max) COLLATE SQL_Latin1_General_CP1_CS_AS

注:“CS”在上面的整理类型是指区分大小写的。

这可以在“服务器数据类型”字段查看使用Visual Studio DBML设计器的属性时输入。

欲了解更多详情,请参见http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html


0
投票
where row.name.StartsWith(q, true, System.Globalization.CultureInfo.CurrentCulture)

0
投票

以下2阶段的方法对我的作品(VS2010,ASP.NET MVC3,SQL Server 2008中,LINQ到SQL):

result = entRepos.FindAllEntities()
    .Where(e => e.EntitySearchText.Contains(item));

if (caseSensitive)
{
    result = result
        .Where(e => e.EntitySearchText.IndexOf(item, System.StringComparison.CurrentCulture) >= 0);
}

0
投票

有时候,存储在数据库值可能会包含空格因此在运行这可能是失败的

String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)

解决这一问题是消除空间,然后转换它的话,那么选择这样的

 return db.UsersTBs.Where(x => x.title.ToString().ToLower().Replace(" ",string.Empty).Equals(customname.ToLower())).FirstOrDefault();

注意,在这种情况下,

customname是要匹配的值与数据库值

UsersTBs是一流的

标题是数据库列


-1
投票

记得有它有效运作之间的查询是否可行,是否区别! LINQ的声明被转换成T-SQL语句执行的目标是SQL Server的,所以你需要考虑,将生产的T-SQL。

使用String.Equals将最有可能(我猜)带回所有从SQL Server行的,然后做在.NET的比较,因为它是一个.NET表达式不能被翻译成T-SQL。

在使用表达式会增加你的数据访问和删除您尽量使用索引的能力等字样。它完全可以在小桌子,你不会注意到其中的差别。在大表上可能表现非常糟糕。

这就是与LINQ存在的问题之一;人们不再认为他们如何写的语句将被履行。

在这种情况下,没有办法做你想要什么,而无需使用一种表达 - 甚至在T-SQL。因此,你可能无法更有效地做到这一点。即使上面给出(使用核对变量)的T-SQL的答案很可能会导致在索引中被忽略,但如果它是一个很大的表,然后如果使用的指标是值得运行的声明来看,在执行计划中看到。

© www.soinside.com 2019 - 2024. All rights reserved.