EF Core 5 - 如何将 EF.Functions.Like 与映射到 JSON 字符串的自定义属性一起使用?

Láz*_*olt 5 c# mysql entity-framework entity-framework-core asp.net-core

在我的一个数据库模型中,我有一个具有自定义类型 ( Dictionary<string, string>) 的属性,它会使用自定义转换器自动与 JSON 相互转换,并作为text字段存储在数据库中。我希望能够使用 MySQL 的LIKE比较器来搜索此 JSON 字段中的字符串,但出现异常。我不关心 JSON 的结构,我可以将其视为简单的文本字段并以这种方式进行搜索。

这是我尝试执行的方法(Sku是复杂类型):

var responseSet = database.Products.Where(p => EF.Functions.Like(p.Sku, "%query%"));
Run Code Online (Sandbox Code Playgroud)

这是我得到的例外:

An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The LINQ expression 'DbSet<ProductObject>()
    .Where(p => __Functions_0
        .Like(
            matchExpression: p.Sku, pattern: __Format_1))' could not be translated. 
            Additional information: 
              Translation of method 'Microsoft.EntityFrameworkCore.MySqlDbFunctionsExtensions.Like' 
              failed. If this method can be mapped to your custom function, 
              see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 
Run Code Online (Sandbox Code Playgroud)

异常中的链接指向一个带有大量交叉引用的长 git 问题,但我无法在其中找到任何有用的内容。

有没有办法可以防止此错误发生并在复杂字段中进行搜索?

Iva*_*oev 8

EF Core值转换器的根本问题是 LINQ 查询是针对客户端类型构建的,然后在后台将其转换为提供程序类型,并且没有标准方法在查询内指定提供程序类型转换。

然而,有一个简单的转换技巧(在我对其他转换相关问题的一些回答中提出,例如How can a JSON_VALUE be conversion to a DateTime with EF Core 2.2?Expression tree to SQL with EF CoreComparing strings as date using EF core 3 ),适用于大多数 EF Core 关系数据库提供商。

在这种情况下,您知道提供程序类型的 CLR 等效项是string,因此您可以使用以下强制转换

p => EF.Functions.Like((string)(object)p.Sku, "%query%")
Run Code Online (Sandbox Code Playgroud)

需要中间转换 toobject来欺骗 C# 编译器接受实际的转换。EF Core 翻译器足够智能,可以删除它(以及不需要时的其他翻译器,如下所示)。