【问题标题】:Entity Framework LINQ contains not case insensitive实体框架 LINQ 包含不区分大小写
【发布时间】:2014-10-08 06:20:33
【问题描述】:

我遇到了一些 Entity Framework 的问题,我只是找不到解决方案。

我想要做的是比较我在服务器上运行的搜索功能的字符串。基本上是:collection.Where(c => c.Name.Contains(searchTerm)); 其中 searchTerm 是用户传递的字符串。

我所看到的任何地方都是:

  1. 使用 toUpper() 更改两个字符串,或

  2. 将排序规则设置为不区分大小写的排序规则。

但是,这些都不适用于我的情况。这是一个没有答案的类似问题:Entity Framework - case insensitive Contains?

使用第一个替代方法将导致获取数据库中的每一行,然后执行 toUpper() 以查看它是否匹配。这在性能方面是不可接受的。

第二种方法似乎更有可能是一个有效的解决方案,但由于某种原因不起作用。我有两个数据库。一本地一远程。远程 MSSQL 数据库设置为排序规则:Finnish_Swedish_CI_AS,这意味着它不区分大小写?本地数据库是自动生成的 localDB,属性“Case Sensitive”设置为 False。

无论我使用这两个数据库中的哪一个,它对用户来说始终是区分大小写的。

有人能解释一下为什么会这样,这样我就可以继续我悲惨的生活吗?

亲切的问候, 罗宾·多贝尔

【问题讨论】:

  • 您的类似问题是 LINQ Contains Case Insensitive 的欺骗,它有一个 IndexOf 解决方案。你可能想试试那个
  • 所以您的意思是 IndexOf 解决方案不会告诉实体框架在比较之前检索每条记录?
  • 您是否阅读过有关不同语言的答案? stackoverflow.com/questions/444798/… 这意味着您应该改用 CultureInfo 类。
  • 您确定搜索正在服务器上执行吗?检查“_collection”的类型?如果是IEnumerable<?>,则查询将在 C# 代码中执行,而不是在数据库服务器上(并且区分大小写)。如果是IQueryable<?>,那么它可能正在数据库服务器上执行。
  • @Grax 可能就是这样。集合类型是ICollection<T>

标签: c# sql-server asp.net-mvc linq entity-framework


【解决方案1】:

使用字符串.Equals

collection.Where(c => string.Equals(c.Name, searchTerm, StringComparison.CurrentCultureIgnoreCase));

另外,您不必担心 null 并且只取回您想要的信息。

使用 StringComparision.CurrentCulture 区分大小写。

collection.Where(c => string.Equals(c.Name, searchTerm, StringComparison.CurrentCulture));

【讨论】:

  • Equals 会尝试完全匹配这个词——这不是我想要的。正如 Dunc 所写,问题是查询是在从服务器获取所有内容后完成的。
  • Entity Framework 5.0 及更高版本在 string.Equals 与 StringComparison 重载引发异常。 docs.microsoft.com/en-us/ef/core/miscellaneous/…
【解决方案2】:

从 cmets 看来,OP 似乎首先将 IQueryable 列表转换为 ICollection,这意味着任何后续 LINQ 都在“本地”运行,而不是有机会转换为 SQL。

例如,

    // Should be IQueryable<T>
    ICollection<User> users = context.Users;

    // This is executed in code rather than SQL, and so is case SENSITIVE
    users = users.Where(c => c.Name.Contains(searchTerm));

这可能有助于调试问题:How do I view the SQL generated by the entity framework?

【讨论】:

    【解决方案3】:

    对我来说,它从来都不区分大小写,但我想这就是我设置数据库的方式。您绝对可以使用将它们都转换为大写的第一个选项,EF 不会将它们拉入内存来执行此操作,只是通知 SQL Server 执行此操作。例如:

    string searchTerm = "Some Text";
    
    dbcontext.Table.Where (t => t.Column.ToLower().Contains(searchTerm.ToLower()));
    

    生成以下 SQL(我用 linqtosql 完成了此操作,但 EF 应该非常相似):

    -- Region Parameters
    DECLARE @p0 NVarChar(1000) = '%some text%'
    -- EndRegion
    SELECT *
    FROM [Table] AS [t0]
    WHERE LOWER([t0].[Column]) LIKE @p0
    

    【讨论】:

    • 好的!感谢您的详尽回答。很有趣知道。然而,这显然不是我的问题。问题是在我的集合上使用 ICollection,导致在服务器上进行比较,这是区分大小写的。
    • 啊,那你的收藏是从哪里来的?如果它是一个集合,那么它已经在内存中,所以调用 .ToUpper() 不会有什么不同。
    猜你喜欢
    • 1970-01-01
    • 2017-09-02
    • 2023-04-02
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2012-02-18
    相关资源
    最近更新 更多