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#使用ML.Net完成人工智能预测

    C#可以使用ML.Net来实现人工智能预测,下面是一些基本的步骤: 1.安装ML.Net。可以通过Visual Studio NuGet包管理器或者官网下载进行安装。 2.准备数据。可以使用Microsoft Excel进行数据采集和整理,将数据存储到CSV格式或者SQL Server数据库中。 3.定义数据结构。为了训练和预测模型,需要定义数据结构。例如,…

    C# 2023年5月15日
    00
  • C# Razor语法规则

    C# Razor语法规则是用于在ASP.NET Web应用程序中编写动态页面的一种语法规则。它允许在HTML页面中嵌入C#代码,以便在客户端浏览器中执行C#代码。下面是C# Razor语法规则的一些基本规则: 1. 嵌入C#代码 使用@符号来嵌入C#代码到HTML页面中。例如: <p>@DateTime.Now.ToString()</p&…

    C# 2023年5月14日
    00
  • C#中的委托和事件详解

    C#中的委托和事件详解 什么是委托? 在C#中,委托(Delegate)是一种特殊的类型,它允许我们将方法作为参数传递给另一个方法,或者把方法存储到一个变量中以便稍后再次使用。简单来说,委托就是一种方法的代理。我们可以使用委托实现一些类似于回调函数的功能。 定义一个委托类型的语法如下: delegate void MyDelegate(string mess…

    C# 2023年5月31日
    00
  • asp.net微软图表控件使用示例代码分享

    这里给出一个完整攻略,讲解如何使用asp.net微软图表控件,包括实现基础图表的绘制、样式和格式设置以及数据绑定等操作。 准备工作 在开始之前,我们需要准备一些工作,如安装相应的软件、添加图表控件、引用相关命名空间等。下面是具体步骤: 安装软件 首先,我们需要安装Microsoft Visual Studio和ASP.NET Web Forms应用程序开发工…

    C# 2023年5月31日
    00
  • C#实现回文检测的方法

    下面我将为你详细讲解“C#实现回文检测的方法”的完整攻略。 什么是回文? 回文是指正读和反读都相同的词或句子。例如:level、noon、deified等。 在计算机编程中,我们经常需要判断一个字符串是不是回文,这就是回文检测。 回文检测的方法 方法一:双指针法 双指针法是最常见的回文检测方法,它的基本思路是从字符串的两端开始,分别向中间移动两个指针,每次比…

    C# 2023年6月7日
    00
  • C# 正则表达式 使用介绍

    C# 正则表达式使用介绍 什么是正则表达式 正则表达式是一种用来描述字符串模式的表达式。它可以用来匹配、查找、替换文本中的字符串,非常适用于数据处理、文本分析等方面。正则表达式的写法非常灵活,可以使用特定的符号来表示文本中的各种模式,并且可以进行组合、嵌套等操作。 C#中的正则表达式 C#中正则表达式的使用由System.Text.RegularExpres…

    C# 2023年6月7日
    00
  • C#图片处理如何生成缩略图的实现

    一、生成缩略图的原理在C#中生成缩略图主要是在原图基础上进行截取,即截取原图的一部分来生成缩略图。需要注意的是,生成缩略图之前需要保证原图文件存在、可读写。 二、使用C#的System.Drawing命名空间生成缩略图C#中使用System.Drawing命名空间下的Image对象来生成缩略图,以下是一个生成缩略图的示例代码: using System.Dr…

    C# 2023年6月6日
    00
  • C# Values:获取 ICollection,其中包含 IDictionary的值

    C# Values 完整攻略 什么是 C# Values? C# Values(中文名:C# 值类型)是指在 C# 编程语言中,除了引用类型(reference types)之外的所有基本数据类型(如整型、浮点型、字符型等)以及由这些基本类型组成的结构体(structs),统称为值类型。值类型存储在堆栈中,这意味着值类型比引用类型更高效,更快速。因为值类型直…

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