You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中Dynamic Linq解析JSON数组查询的实现问题

解决Dynamic Linq查询JSON数组字段的问题

针对你用Dynamic Linq查询MyTable中JSON数组字段的需求,这里提供三种可行方案,按推荐优先级排序:

方案1:借助EF Core原生JSON查询能力(无需扩展Dynamic Linq)

如果你的项目基于EF Core,直接用EF内置的JSON函数构建查询,Dynamic Linq可以直接识别这些函数调用,这是最简便的方案。

假设JSONCustomPropertiesValues是字符串类型(存储JSON数组),构造如下Dynamic Linq查询字符串:

string dynamicQuery = @"JSONCustomPropertiesValues != null && EF.Functions.JsonQuery(JSONCustomPropertiesValues, '$').Any(y => (int)y.CustomProperty_Id == @0 && y.IntValue != null && (int?)y.IntValue == @1)";
var parms = new object[] { 27, 48 };
var result = query.Where(dynamicQuery, parms).ToList();
  • EF.Functions.JsonQuery会将JSON字符串解析为可查询集合,EF Core会自动转换为数据库原生的JSON查询语句
  • 用y.CustomProperty_Id属性访问替代索引器y["CustomProperty_Id"],Dynamic Linq对动态对象属性访问的支持更稳定
  • 若使用PostgreSQL等其他数据库,替换为对应EF函数即可(比如PostgreSQL用EF.Functions.JsonbArrayElements)

方案2:扩展Dynamic Linq支持JArray操作

如果必须使用JArray.Parse的方式,需要扩展Dynamic Linq的解析能力,让它识别JArray和JToken的相关操作:

步骤1:注册自定义类型与扩展方法

在项目启动时配置Dynamic Linq:

using System.Dynamic.Linq;
using Newtonsoft.Json.Linq;

DynamicLinq.Configure(config =>
{
    // 注册JArray、JToken类型
    config.AddType(typeof(JArray));
    config.AddType(typeof(JToken));
    // 注册JArray.Parse方法
    config.AddMethod(typeof(JArray), nameof(JArray.Parse), new[] { typeof(string) });
    // 注册自定义扩展方法,替代JToken索引器
    config.AddExtensionMethod(typeof(JTokenExtensions), nameof(JTokenExtensions.GetValue));
});

// 自定义扩展方法,包装JToken的索引访问
public static class JTokenExtensions
{
    public static object GetValue(this JToken token, string key)
    {
        return token[key];
    }
}

步骤2:构造Dynamic Linq查询字符串

现在可以用扩展后的语法编写查询:

string dynamicQuery = @"JSONCustomPropertiesValues != null && JArray.Parse(JSONCustomPropertiesValues).Any(y => (int)y.GetValue(""CustomProperty_Id"") == @0 && y.GetValue(""IntValue"") != null && (int?)y.GetValue(""IntValue"") == @1)";
var parms = new object[] { 27, 48 };
var result = query.Where(dynamicQuery, parms).ToList();
  • Dynamic Linq默认不支持索引器语法(y["key"]),所以用自定义GetValue方法替代
  • 必须完成类型和方法注册,否则Dynamic Linq会无法解析相关调用

方案3:提前解析JSON字段(适用于内存集合)

如果查询的是内存集合而非数据库IQueryable,可以先将JSON字段解析为JArray,再用Dynamic Linq查询:

// 先把JSON字段解析为JArray,加载到内存
var dataWithParsedJson = query.Select(x => new 
{
    Original = x,
    ParsedProperties = x.JSONCustomPropertiesValues != null ? JArray.Parse(x.JSONCustomPropertiesValues) : null
}).ToList();

// 用Dynamic Linq查询内存集合
string dynamicQuery = @"ParsedProperties != null && ParsedProperties.Any(y => (int)y[""CustomProperty_Id""] == @0 && y[""IntValue""] != null && (int?)y[""IntValue""] == @1)";
var parms = new object[] { 27, 48 };
var result = dataWithParsedJson.AsQueryable().Where(dynamicQuery, parms).Select(item => item.Original).ToList();
  • 该方案无需扩展Dynamic Linq,但会将数据全部加载到内存,不适合大数据量场景

内容的提问来源于stack exchange,提问作者A.C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:55:30