Linq to Entities:在NText字段上使用ToLower()

Jul*_*n N 13 c# linq-to-entities sql-server-2005

我正在使用SQL Server 2005,带有区分大小写的数据库.

在搜索功能中,我需要使用"where"子句创建Linq To Entities(L2E)查询,该子句使用以下规则将多个字符串与数据库中的数据进行比较:

  1. 比较是一个"包含"模式,而不是严格比较:因为L2E中允许字符串的Contains()方法很容易
  2. 比较必须不区分大小写:我在两个元素上使用ToLower()来执行不敏感的比较.

所有这些都表现得非常好,但我遇到了以下异常:"我的一个字段上的参数数据类型ntext对于较低函数的参数1无效".

看来该字段是一个NText字段,我无法对其执行ToLower().
我该怎么做才能在NText字段上执行不区分大小写的Contains()?

Cra*_*ntz 29

切勿用于.ToLower()执行不区分大小写的比较.原因如下:

  1. 这可能是错误的(您的客户端排序规则可能是土耳其语,而您的数据库排序规则可能不是).
  2. 这是非常低效的; SQL Emitted LOWER而不是=不区分大小写的排序规则.

相反,使用StringComparison.OrdinalIgnoreCaseStringComparison.CurrentCultureIgnoreCase:

var q = from f in Context.Foos
        where f.Bar.Equals("hi", StringComparison.OrdinalIgnoreCase)
        select f;
Run Code Online (Sandbox Code Playgroud)

但是因为Contains()有一个问题:不像Equals,StartsWith等等,它没有StringComparison参数的重载.为什么?好问题; 问微软.

结合SQL Server的限制LOWER意味着没有简单的方法来做你想做的事情.

可能的解决方法可能包括:

  • 使用全文索引,并在过程中进行搜索.
  • 如果可能,请使用EqualsStartsWith代替您的任务
  • 更改列的默认排序规则?


小智 5

在此处使用lambda表达式并创建可以处理lower子句的中间列表.

var q = Context.Foos.ToList().Where(s => s.Bar.ToLower().Contains("hi"));
Run Code Online (Sandbox Code Playgroud)

效率不是很高,但确实有效.如果你的where子句中有其他谓词,那么它对你有利:

var q = Context.Foos.Where(p => p.f1 == "foo" && p.f2 == "bar").
            ToList().Where(s => s.Bar.ToLower().Contains("hi"));
Run Code Online (Sandbox Code Playgroud)

  • 同意,我刚刚提到它,以便使用这种技术的新人知道它真正做了什么(我总是惊讶地看到有多少人使用L2E而不知道下面发生了什么).因此,对于大表,它可能会对性能/内存产生重大影响.就我而言,表现并不重要. (2认同)