EF Core 8.x+Pomelo适配MariaDB:JSON数组长度查询异常
解决EF Core 8.x + MariaDB中LINQ查询JSON列长度的问题
问题根源
你使用a.Data.Count时,EF Core错误将其解析为访问JSON对象的Count属性(生成JSON_EXTRACT(a.Data, '$.Count')),但实际需求是获取JSON结构的长度,对应MariaDB的JSON_LENGTH()函数。
解决方案(保留EF实体跟踪)
方法1:使用Pomelo提供的原生JSON函数扩展
Pomelo.EntityFrameworkCore.MySql内置了MariaDB/MySQL的JSON函数映射,直接调用即可:
确保已安装依赖包(已安装可跳过):
Install-Package Pomelo.EntityFrameworkCore.MySql -Version 8.0.2 Install-Package Pomelo.EntityFrameworkCore.MySql.Json.Microsoft -Version 8.0.2在查询中使用
EF.Functions.MySql.JsonLength():using Pomelo.EntityFrameworkCore.MySql.Functions; var list = dbContext.Analyses.Include(a => a.Site) .Where(a => EF.Functions.MySql.JsonLength(a.Data) > 0) .ToList();此方法会生成正确的SQL:
SELECT `a`.`Id`, `a`.`Data`, `a`.`LastAnalysisDateTime`, `a`.`Result`, `a`.`SiteId`, `s`.`Id`, `s`.`Domain`, `s`.`LastResolvedDateTime`, `s`.`ResolvedDomain` FROM `Analyses` AS `a` INNER JOIN `Sites` AS `s` ON `a`.`SiteId` = `s`.`Id` WHERE JSON_LENGTH(`a`.`Data`) > 0
方法2:自定义DbFunction映射(兼容更多场景)
如果需要更灵活的控制,可以手动映射MariaDB的JSON_LENGTH函数:
在你的DbContext类中添加静态方法并标记
[DbFunction]:using Microsoft.EntityFrameworkCore; public class YourDbContext : DbContext { // 映射MariaDB的JSON_LENGTH函数 [DbFunction("JSON_LENGTH", IsBuiltIn = true)] public static int JsonLength(object json) { // 仅用于EF查询翻译,运行时不会执行 throw new NotImplementedException("This method is for EF Core translation only."); } // ... 其他DbSet和配置代码 }在LINQ查询中调用自定义函数:
var list = dbContext.Analyses.Include(a => a.Site) .Where(a => YourDbContext.JsonLength(a.Data) > 0) .ToList();
关键说明
- 无论你的
Data列映射为string、JsonElement、JsonDocument还是自定义.NET实体类,上述方法都能正常工作,EF会自动将其转换为对应的数据库JSON列引用。 - 该方案完全保留EF的实体跟踪和对象映射能力,无需使用原生SQL绕过EF。
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

