国际字符不能与SQL Sever where语句一起使用

时间:2016-03-04 22:37:33

标签: c# sql-server entity-framework azure-sql-database

我在本地数据库(SQL Server 2012)和生产(Azure SQL)上遇到国际符号数据编码问题

最初它发生在Entity Framework 7和Asp5-rc1中,但我设法使用下面的简单SQL查询重现它。

select Source 
from tag 
where Source like '%dzie%'

返回正确显示ń的行

  

dzień.txt

select Source 
from tag 
where Source like '%dzień%' // additional 'ń' character at the end

返回空表

SQL和Entity框架都返回看起来合法的值(使用ń),但是当我在ń语句中使用where时,数据库不返回任何结果。

然而,当我执行以下代码i 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

此时返回正确显示ń的行

  

dzień.txt

我需要每个角色都使用where语句。我该怎么做才能使它工作,特别是在Azure上。

2 个答案:

答案 0 :(得分:0)

试试这个;

_context.Tags.Where(tag => tag.Source.Contains("dzień.txt")) 

这应该将N'添加到SQL查询中。在执行LINQ时运行SQL Server Profiler,看看它如何将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 Server中不存在的任何项目集合都被视为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;
}

答案 1 :(得分:0)

问题是由于ń是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ń%'

你应该看到所需的结果。