【问题标题】:Linq to Entities : using ToLower() on NText fieldsLinq to Entities:在 NText 字段上使用 ToLower()
【发布时间】:2010-03-12 10:14:40
【问题描述】:

我使用的是 SQL Server 2005,数据库区分大小写。

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

  1. 比较是“包含”模式,而不是严格比较:很简单,因为在 L2E 中允许使用字符串的 Contains() 方法
  2. 比较必须不区分大小写:我对两个元素都使用 ToLower() 来执行不区分大小写的比较。

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    改为使用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
    • 更改列的默认排序规则?

    【讨论】:

    • hum... 我猜你告诉我使用 ToLower() 是错误的,但我没有其他解决方案: - 更改排序规则对于某些搜索条件来说工作量太大和风险 - 等于 & StartsWith 不适合这里的需要。我正在考虑将 NText 字段转换为 NVarchar 并限制用户输入......在我的情况下,性能并不重要。
    • 我只是想告诉你选择是什么,而不是断言存在一些适合你的理想选择......
    【解决方案2】:

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

    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"));
    

    【讨论】:

    • 这是 Linq to Entities :目标是生成适当的 SQL 请求。您的解决方案将抓取表的所有行(或使用其他条件过滤的行),然后应用过滤器。事实上,这绝对不是有效的:)。但我承认它会起作用!
    • 我认为目标是对实体进行适当的 linq?在效率方面...有时当您的客户尖叫着要修复该死的错误而您的老板正在敲打他们的手指给您带来臭眼时...效率和性能被高度高估了,除非它们不是。仅仅因为某些东西可以优化并不意味着它必须是。
    • 同意,我刚刚提到它是为了让使用这种技术的新人知道它的真正作用(看到有多少人使用 L2E 却不知道下面发生了什么,我总是很惊讶)。因此,对于大表,它可能会对性能/内存产生重大影响。就我而言,性能并不重要。
    • 当然,人们必须知道,好点。这不适用于大量数据。
    【解决方案3】:

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

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

    从表名中选择 * where theColumn like '%key%'

    然后将此视图加载到 EF 中。

    生活越来越轻松!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      相关资源
      最近更新 更多