国际字符不适用于 SQL Sever where 语句
International characters not working with SQL Sever where statement
我在本地数据库 (SQL Server 2012) 和生产环境 (Azure SQL) 上遇到国际符号数据编码问题
最初它发生在 Entity Framework 7 和 Asp5-rc1 上,但我设法用下面的简单 SQL 查询重现了它。
select Source
from tag
where Source like '%dzie%'
Returns 一行 ń
正确显示
dzień.txt
select Source
from tag
where Source like '%dzień%' // additional 'ń' character at the end
Returns 空table
SQL 和 Entity framework return 值看起来都合法(使用 ń
),但是当我在 where
中使用 ń
时语句,数据库 return 没有结果。
然而,当我在 Management Studio 中执行以下代码时
update tag
set Source = 'dzień.txt'
where Id = 'my id'
比这个查询(和以前一样)
select Source
from tag
where Source like '%dzień%' // additional 'ń' character at the end
这次 return 一行 ń
正确显示
dzień.txt
我需要每个字符都使用 where
语句。我应该怎么做才能让它发挥作用,尤其是在 Azure 上。
试试这个;
_context.Tags.Where(tag => tag.Source.Contains("dzień.txt"))
这应该将 N'
添加到 SQL 查询中。 运行 SQL Server Profiler 执行 LINQ 并查看它如何将 LINQ 转换为 SQL。
另一个选项是 Equals
运算符。这相当于 SQL =
运算符。如果您认为有可能出现混合大小写的名称,您可以使用 CurrentCultureIgnoreCase
_context.Tags.Where(tag => tag.Source.Equals("dzień.txt", StringComparison.CurrentCulture))
注意 StringComparison.CurrentCulture
。
确保您在 Source
字段上有索引。它将显着提高性能。
已更新以显示如何查询项目集合
这是 EF 的缺点之一。对于非 sql 类型的集合,您不能使用 LINQ to SQL。基本上,您的 SQL 服务器中不存在的任何项目集合都被视为 EF 未知。
所以这是一个选项;
public IENumerable<Tag> SearchTags(IENumerable<string> toBeSearchedTags)
{
List<Tag> availableTags = new List<Tag>();
foreach(var stag in toBeSearchedTags)
{
var availableTag = _context.Tags.FirstOrdefault(tag => tag.Source.Equals(stag, StringComparison.CurrentCulture))
if(availableTag != null)
{
availableTags.Add(availableTag);
}
}
return availableTags;
}
问题是由于 ń 是一个 Unicode 字符,而您的字符串 '%dzień%' 是未标记为 Unicode 字符串。 Unicode 字符串由 N''
前缀标记。
要在 Management Studio 中对此进行测试,只需 运行
select 'dzień'
结果是 dzien
。如果将字符串更改为 Unicode,
select N'dzień'
你得到 dzień
.
请注意,N''
表示法是 feature of T-SQL,不需要在分析器或其他日志记录中加以区分。
将您的查询更改为
select Source
from tag
where Source like N'%dzień%'
你应该会看到想要的结果。
我在本地数据库 (SQL Server 2012) 和生产环境 (Azure SQL) 上遇到国际符号数据编码问题
最初它发生在 Entity Framework 7 和 Asp5-rc1 上,但我设法用下面的简单 SQL 查询重现了它。
select Source
from tag
where Source like '%dzie%'
Returns 一行 ń
正确显示
dzień.txt
select Source
from tag
where Source like '%dzień%' // additional 'ń' character at the end
Returns 空table
SQL 和 Entity framework return 值看起来都合法(使用 ń
),但是当我在 where
中使用 ń
时语句,数据库 return 没有结果。
然而,当我在 Management Studio 中执行以下代码时
update tag
set Source = 'dzień.txt'
where Id = 'my id'
比这个查询(和以前一样)
select Source
from tag
where Source like '%dzień%' // additional 'ń' character at the end
这次 return 一行 ń
正确显示
dzień.txt
我需要每个字符都使用 where
语句。我应该怎么做才能让它发挥作用,尤其是在 Azure 上。
试试这个;
_context.Tags.Where(tag => tag.Source.Contains("dzień.txt"))
这应该将 N'
添加到 SQL 查询中。 运行 SQL Server Profiler 执行 LINQ 并查看它如何将 LINQ 转换为 SQL。
另一个选项是 Equals
运算符。这相当于 SQL =
运算符。如果您认为有可能出现混合大小写的名称,您可以使用 CurrentCultureIgnoreCase
_context.Tags.Where(tag => tag.Source.Equals("dzień.txt", StringComparison.CurrentCulture))
注意 StringComparison.CurrentCulture
。
确保您在 Source
字段上有索引。它将显着提高性能。
已更新以显示如何查询项目集合
这是 EF 的缺点之一。对于非 sql 类型的集合,您不能使用 LINQ to SQL。基本上,您的 SQL 服务器中不存在的任何项目集合都被视为 EF 未知。
所以这是一个选项;
public IENumerable<Tag> SearchTags(IENumerable<string> toBeSearchedTags)
{
List<Tag> availableTags = new List<Tag>();
foreach(var stag in toBeSearchedTags)
{
var availableTag = _context.Tags.FirstOrdefault(tag => tag.Source.Equals(stag, StringComparison.CurrentCulture))
if(availableTag != null)
{
availableTags.Add(availableTag);
}
}
return availableTags;
}
问题是由于 ń 是一个 Unicode 字符,而您的字符串 '%dzień%' 是未标记为 Unicode 字符串。 Unicode 字符串由 N''
前缀标记。
要在 Management Studio 中对此进行测试,只需 运行
select 'dzień'
结果是 dzien
。如果将字符串更改为 Unicode,
select N'dzień'
你得到 dzień
.
请注意,N''
表示法是 feature of T-SQL,不需要在分析器或其他日志记录中加以区分。
将您的查询更改为
select Source
from tag
where Source like N'%dzień%'
你应该会看到想要的结果。