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

LINQ查询使用JsonConvert.Deserialize报错 无需调用ToList()如何实现

错误原因

这个异常的本质是LINQ to 数据库提供器(一般是EF Core)无法将JsonConvert.DeserializeObject方法转换为可执行的SQL语句,只能在内存中执行C#方法逻辑。你追加ToList()后,会先把符合FormMasterStatus == "pending"条件的所有数据加载到内存中,后续的Where就变成了LINQ to Objects操作,自然可以正常调用Newtonsoft.Json的反序列化方法。

无需调用ToList()的实现方案

方案1:使用数据库原生JSON查询(最优,全程不加载冗余数据到内存)

如果你的数据库支持JSON查询(主流的SQL Server、PostgreSQL、MySQL均支持),且使用EF Core 7及以上版本,可以直接用EF内置的JSON函数映射,将整个查询逻辑翻译成数据库端的SQL执行,完全不需要拉取数据到内存处理。
以SQL Server为例,你只需要先确认FormMasterApprovalCcb字段在实体配置中标记为JSON类型,再按如下方式写查询即可:

var c = content.FormMasterLists
    .Where(x => x.FormMasterStatus == "pending")
    .Where(x => EF.Functions.JsonContains(
        x.FormMasterApprovalCcb,
        "{\"ApproverEmail\": \"christ\"}",
        "$.Group[*].Department[*].ApprovalCCBLevel[*].Approver[*]"
    ));

你可以根据自己使用的数据库类型调整对应的JSON函数,不同数据库的函数名和JSON路径写法略有差异,核心逻辑都是让EF提供器识别到可以将JSON匹配逻辑转换为原生数据库操作。

方案2:使用AsEnumerable()替代ToList()(内存优化版)

如果你使用的EF版本较低,或者数据库不支持JSON查询,无法做到完全不在内存中处理,也可以用AsEnumerable()替代ToList()优化内存占用:

var c = content.FormMasterLists
    .Where(x => x.FormMasterStatus == "pending")
    .Select(x => x.FormMasterApprovalCcb) // 仅查询需要的JSON字段,减少数据传输量
    .AsEnumerable() // 切换为LINQ to Objects模式,流式加载数据,不会一次性生成全量列表
    .Where(json => JsonConvert.DeserializeObject<ApprovalCCB>(json).Group
        .SelectMany(g => g.Department)
        .SelectMany(d => d.ApprovalCCBLevel)
        .SelectMany(l => l.Approver)
        .Any(a => a.ApproverEmail == "christ"));

AsEnumerable()不会像ToList()一样立刻把所有查询结果加载到内存列表中,而是逐个返回数据处理,数据量大的时候内存开销会小很多。

内容的提问来源于stack exchange,提问作者Chris Tuang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 15:36:03