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

时间:2010-03-12 10:14:41

标签: c# sql-server-2005 linq-to-entities

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

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

  1. 比较是“包含”模式,不是严格比较:因为L2E中允许使用字符串的Contains()方法
  2. 比较必须不区分大小写:我在两个元素上使用ToLower()来执行不敏感的比较。
  3. 所有这些都表现得很好,但我遇到了以下异常: 在我的一个字段上,“参数数据类型ntext对于较低函数的参数1无效”。

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

3 个答案:

答案 0 :(得分:29)

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

  1. 这可能是错的(您的客户端整理可能是土耳其语,而不是您的数据库整理)。
  2. 高度效率低下; SQL Emitted为LOWER而不是=,并且不区分大小写。
  3. 相反,请使用StringComparison.OrdinalIgnoreCaseStringComparison.CurrentCultureIgnoreCase

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

    但对于Contains(),存在一个问题:与EqualsStartsWith等不同,它没有StringComparison参数的重载。为什么?好问题;问微软。

    结合SQL Server对LOWER的限制意味着没有简单的方法可以做你想要的。

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

    • 使用全文索引,然后在过程中进行搜索。
    • 如果可能,请使用EqualsStartsWith
    • 更改列的默认排序规则?

答案 1 :(得分:5)

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

var q = Context.Foos.ToList().Where(s => s.Bar.ToLower().Contains("hi"));

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

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

答案 2 :(得分:0)

正如我们所知,这是一个非常“错误”的情况。 它让我很烦恼。

今天,我决定创建一个视图:

从tableName中选择* 其中theColumn喜欢'%key%'

然后将此视图加载到EF。

生活变得轻松!