Entity Framework Core 大小写敏感处理

 

可以使用'StringComparison'吗?

在数据库查询操作中,不可避免去考虑字母大小写的问题,比如要在Movie表中查找“X-Men”这部电影,为了不区分字母大小写,按照Linq to memory的习惯,可能会写出如下代码:

DbContext.DbSet<Movie>
  .Where(item => string.Equals(item.Title, "X-Men", StringComparison.InvariantCultureIgnoreCase)

但是上述代码执行会报错,提示 'StringComparison'参数不支持。

InvalidOperationException: The LINQ expression 'DbSet<Movie>() .Where(m => string.Equals( a: m.Genre, b: __MovieGenre_0, comparisonType: InvariantCultureIgnoreCase))' could not be translated. 
Additional information: Translation of the 'string.Equals' overload with a 'StringComparison' parameter is not supported. 
See https://go.microsoft.com/fwlink/?linkid=2129535 for more information. 
Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. 
See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

怎么解决这个问题呢?如果你用的是SQL server或MySQL,那么很简单,去掉“StringComparison.InvariantCultureIgnoreCase”这个参数就可以了,因为他们是默认大小写不敏感的。如果用的是大小写敏感的数据库,比如PostgreSQL,就需要做一些特殊处理了,后面会讲到。

对于这类问题有一个暴力的解决方法,就是按报错提示的那样在查询客户端做筛选:

DbContext.DbSet<Movie>
  .ToList()
  .Where(item => string.Equals(item.Title, "X-Men", StringComparison.InvariantCultureIgnoreCase)

这样做的本质是返回所有的Movie,然后在内存中做Title匹配查询(Linq to memory),而不是在DB中做Title的匹配查询,所以不会报 'StringComparison'参数不支持的错误。这种方法在绝大多数场景下是不推荐的,因为 1. 性能差,查询是在内存中不是在DB中,2. 占用内存,返回了整张表

 

为什么不能使用'StringComparison'?

前面讲到有的数据库是默认大小写不敏感的:SQL server,MySQL;有的数据库是默认大小写敏感的:PostgreSQL。那么数据库中大小写敏感与否是由什么控制的呢,排序规则(Collation,一组规则,用于确定文本值的排序和相等性比较方式,可以在数据库,表和列上创建排序规则,排序规则是隐式继承的,比如在数据库上创建了排序规则,没有在表上创建排序规则,那么表会默认使用数据库的排序规则,列同理)。因为EF core不知道数据库,表,列支持/应用了什么样的排序规则,所以'StringComparison'是没有意义的,EF core会将  string.Equals 转化成数据库的相等( = )操作,由数据库根据列上应用的排序规则来决定是否区分大小写。

 

如何在查询中设置区分大小写与否?

既然区分大小写是由排序规则决定的,我们可以通过在查询中指定排序规则的方式来来设置是否区分大小写,例如SQL Server默认是不区分大小写的,我们可以通过 EF.Functions.Collate 来指定一个大小写敏感的排序规则"SQL_Latin1_General_CP1_CS_AS"来达到精确匹配的目的

DbContext.DbSet<Movie>
    .Where(m => EF.Functions.Collate(item.Title, "SQL_Latin1_General_CP1_CS_AS") == "X-Men")

但是这种显示指定排序规则的方法也不是非常推荐的,因为他会导致索引匹配失败,进而影响查询性能。索引隐式继承列上的排序规则,当显示指定的排序规则和创建索引时指定的排序规则(PostgreSQL支持在创建索引时指定排序规则)或列的排序规则不一致时,会导致索引匹配失败,进而导致查询不能应用索引,这也是EF Core没有将'StringComparison'转换成排序规则的另一个原因。

因此一个相对完善的解决方案是,根据业务模型在列上指定合适的排序规则,而不是在代码中设置。如果数据库支持在列上创建多个索引,你也可以用显示指定排序规则的方式根据业务场景切换排序规则来匹配正确的索引。

 

参考文档:

https://learn.microsoft.com/en-us/ef/core/miscellaneous/collations-and-case-sensitivity

https://learn.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-ver16

https://www.postgresql.org/docs/current/collation.html

原文链接:https://www.cnblogs.com/Tiger-Lu/archive/2023/04/13/17311560.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Entity Framework Core 大小写敏感处理 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • 详解C# 中Session的用法

    详解C# 中Session的用法 什么是Session Session 是指会话,在 Web 应用程序中,它表示从客户端发来的一系列HTTP请求和响应交互。Session 可以用来存储和检索任何类型的对象,且这些对象在整个 Session 生命周期内都可以使用。在 ASP.NET 中可以使用 Session 对象来在服务器上存储和检索用户特定的信息。Sess…

    C# 2023年6月7日
    00
  • VS2019使用快捷键将代码对齐的方法

    下面是VS2019使用快捷键将代码对齐的方法的详细讲解: 1. 概述 在编写代码时,我们通常需要把代码对齐,以提高可读性。手动对齐耗时耗力,使用快捷键则可快速完成对齐操作。VS2019提供了一系列快捷键,可以帮助我们快速对齐代码。 2. 快捷键对应功能 下面是常用的几个快捷键及对应的代码对齐功能: Ctrl+K+D 快速格式化代码,实现对齐 Ctrl+K+F…

    C# 2023年6月3日
    00
  • C# 判断字符串为空的几种办法

    下面是讲解“C#判断字符串为空的几种办法”的完整攻略: 1. 判断字符串是否为 null 或者空字符串 使用 String.IsNullOrEmpty() 方法可以判断字符串是否为 null 或者空字符串。具体实现代码如下: string str = ""; if (String.IsNullOrEmpty(str)) { Console…

    C# 2023年5月15日
    00
  • C# 中const,readonly,static的使用小结

    下面是对于“C#中const,readonly,static的使用小结”的详细讲解。 前言 在C#开发中,我们常常会使用const,readonly和static这三个关键字,它们都可以用来定义变量,但具有不同的作用。 const const是常量的意思,其特点是在编译时期已经固定下来了,不可改变。 在C#中,const定义的变量必须在声明时初始化,而且只能…

    C# 2023年5月15日
    00
  • C#实现统计字数功能的方法

    下面是“C#实现统计字数的功能”的完整攻略: 一、需求分析 在进行编码之前,我们需要先分析需求,明确要实现的功能。在这个任务中,我们需要实现统计一段文本中包含的字符数和单词数的功能。 字符数的统计比较简单,只需要计算文本长度即可。而对单词数的统计涉及到对文本内容的分词和统计,需要采用一定的算法实现。 二、实现步骤 1. 统计字符数 要统计字符数,首先需要获取…

    C# 2023年6月1日
    00
  • 简单学习C#中的泛型方法使用

    简单学习C#中的泛型方法使用 什么是泛型 泛型是C#中的一种特殊类型或方法,它允许我们编写可以在多个类型上操作的代码,而无需在每种类型上编写多个重复的代码。它为我们提供了一种在编译时类型安全检查的方式,以更好的在不同情况下进行重用。 泛型方法的定义 下面是一个简单的泛型方法的定义。 public static void PrintArray<T>…

    C# 2023年6月7日
    00
  • 前端构建 Less入门(CSS预处理器)

    前端构建 Less入门(CSS预处理器) CSS预处理器是一种把CSS编写过程中所需要的变量、混合(类似于函数)、继承等操作实现的一种技术。当我们大规模开发Web前端项目时,使用CSS预处理器可以提高CSS代码的复用性和可维护性。 Less是一种广泛使用的CSS预处理器,本文将介绍Less的基本使用方法和常用功能。 安装Less 在使用Less之前,需要首先…

    C# 2023年6月6日
    00
  • ASP.NET Core使用功能开关控制路由访问操作

    ASP.NET Core使用功能开关控制路由访问操作 在ASP.NET Core应用程序中,我们可以使用功能开关来控制路由访问操作。功能开关是一种机制,可以在应用程序中启用或禁用特定的功能。在本文中,我们将介绍如何使用功能开关来控制路由访问操作,并提供一些示例来说明如何使用它们。 安装Microsoft.FeatureManagement.AspNetCor…

    C# 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部