文本搜索,例如使用LINQ的SQL COLLATE Latin1_General_CI_AI

时间:2018-11-29 10:43:23

标签: c# sql-server entity-framework linq collation

我可以通过SQL搜索没有问题的客户表。

select Name
from Customers
where  Name COLLATE Latin1_General_CI_AI like '%ozgur%'

此查询可以找到“özgür”

当我将该表放置到缓存中并尝试使用linq搜索该表时,找不到通过“ ozgur”搜索词找到的“özgür”。

在C#LINQ中是否有类似的方式使用Latin1_General_CI_AI?

2 个答案:

答案 0 :(得分:2)

我发现唯一使用归类的地方是Entity SQL的ORDER BY子句。

您可以使用SqlQuery,如图here所示,使用使用COLLATE子句的SQL字符串(当然带有参数):

var query = "select Name from Customers " +
           " where  Name COLLATE Turkish_CI_AI like @name";
var results = myContext.Customers
                       .SqlQuery(query,new SqlParameter("@name","%ozgur%"))
                       .ToList();

尽管如此,我还是建议谨慎。 LIKE '%...%'无法从覆盖name字段的任何索引中受益,而必须搜索整个表。甚至Name = @name COLLATE ...可能不使用排序规则与建立索引的排序规则不匹配的任何索引。

您应该考虑使用full text search索引并对特定单词进行全文搜索查询,例如:

SELECT Name from Customers WHERE CONTAINS(Name ,@thatName)

更新

另一种选择是使用拦截器来更改由子句生成的SQL,如本SO question所示。该拦截器使用正则表达式将LIKE替换为CONTAINS。可以使用一个更简单的表达式在COLLATE

之前插入LIKE子句

该代码并非易事,但至少是一个选择。

答案 1 :(得分:0)

为什么不对Unicode值使用以下filer子句

转换归类类型将导致性能问题并阻止索引的使用

public abstract class BaseCache
{
  private readonly object cacheLock = new object();
  protected ObjectCache cache = MemoryCache.Default;

  public List<string> Get()
  {
        // for example. It could be anywhere and return any type.
        ChildLogic();

        var data = cache.Get(key);

        if (data != null)
            return;

        lock (cacheLock)
        {
            // Check again.
            data = cache.Get(key);

            if (data != null)
                return;

            // Populate, and return.
            PopulateFromElsewhere();
        }
  }

  protected abstract void ChildLogic();
  protected abstract void PopulateFromElsewhere();
}