序列化 JSON 时崩了?99% 是 EF 延迟加载惹的祸,三种解法拿走不谢
一、先看一个“翻车”现场假设我们有这么三层数据主表fin_voucher_rule_master凭证规则明细表fin_voucher_rule_detail规则明细条件表fin_voucher_rule_condition明细下的条件关系很简单一个主表有多个明细一个明细有多个条件。DAL 层数据访问层代码public static Listfin_voucher_rule_master GetFin_Voucher_Rule_Masters(string name) { using (var db new PcbEntities()) { var q db.fin_voucher_rule_master.AsNoTracking(); if (!string.IsNullOrEmpty(name)) q q.Where(x x.business_type.Contains(name)); return q.ToList(); } }服务层代码转成 JSON 返回给前端public static string GetFin_Voucher_Rule_Masters(string name) { var list DAL.VoucherRuleMasterDAL.GetFin_Voucher_Rule_Masters(name); string json ZhPcb.Common._Json.GetJsonfin_voucher_rule_master(list); json {\total\: list.Count ,\rows\: json }; return json; }看着没啥问题吧结果一跑崩了System.ObjectDisposedException: 此 ObjectContext 实例已释放不可再用于需要连接的操作。刚子第一次遇到的时候也是一脸懵我明明ToList()了数据都查出来了怎么还说“上下文已释放”二、原因分析都是“延迟加载”惹的祸啥是延迟加载简单说EF 默认开启了一个“懒汉模式”你查主表的时候它只把主表自己的字段比如 Id、Name给你。至于主表关联的明细fin_voucher_rule_detail它先不查等你真正用到的时候它再偷偷去数据库查。这个“偷偷查”的动作就叫延迟加载。为啥ToList()之后还会查数据库很多人以为ToList()就万事大吉了数据全在内存里了。错ToList()只加载了你明确查询的那些字段。你没有Include的导航属性EF 不会主动加载。等你一访问它比如 JSON 序列化器想把它转成字符串EF 才反应过来“哎呀这个还没查呢我赶紧去数据库拿。”——结果发现DbContext已经在using外面被释放了于是报错。本案例的执行流程拆解版DAL 层using (var db new PcbEntities())创建数据库连接。执行.AsNoTracking().Where(...).ToList()只加载了主表自身的字段。using块结束db被释放连接关闭。服务层调用 JSON 序列化工具。序列化器很“勤奋”它会递归遍历master对象的所有属性包括导航属性比如fin_voucher_rule_detail。当序列化器访问master.fin_voucher_rule_detail时EF 的代理对象尝试延迟加载——但DbContext已经没了于是抛出ObjectDisposedException。划重点你让 EF 帮你查主表它只给了你主表。你以为完事了结果序列化的时候非要去看明细EF 说“那我再去数据库拿”可数据库连接早就关了。不崩你崩谁三、解决方案三种按需选方案一关掉延迟加载最简单在DbContext里把延迟加载功能关掉。这样 EF 就不会“偷偷”查数据库了访问导航属性只会得到null或空集合不会报错。using (var db new PcbEntities()) { db.Configuration.LazyLoadingEnabled false; // EF6 写法 // 如果是 EF Coredb.ChangeTracker.LazyLoadingEnabled false; var q db.fin_voucher_rule_master.AsNoTracking(); // ... return q.ToList(); }优点改一行代码搞定省心。缺点如果业务上确实需要明细数据你得自己Include。划重点Web 应用一般推荐全局关掉延迟加载然后在需要的地方手动Include。这样最可控。方案二提前加载导航属性Eager Loading用Include和ThenInclude告诉 EF“把明细和条件也一起查出来别偷懒。”EF Core 写法推荐using Microsoft.EntityFrameworkCore; public static Listfin_voucher_rule_master GetFin_Voucher_Rule_Masters(string name) { using (var db new PcbEntities()) { var q db.fin_voucher_rule_master .Include(m m.fin_voucher_rule_detail) .ThenInclude(d d.fin_voucher_rule_condition) .AsNoTracking(); if (!string.IsNullOrEmpty(name)) q q.Where(x x.business_type.Contains(name)); return q.ToList(); } }EF6 写法不支持ThenInclude用字符串或Selectusing System.Data.Entity; public static Listfin_voucher_rule_master GetFin_Voucher_Rule_Masters(string name) { using (var db new PcbEntities()) { var q db.fin_voucher_rule_master .Include(fin_voucher_rule_detail.fin_voucher_rule_condition) .AsNoTracking(); // 或者用 lambda.Include(x x.fin_voucher_rule_detail.Select(d d.fin_voucher_rule_condition)) if (!string.IsNullOrEmpty(name)) q q.Where(x x.business_type.Contains(name)); return q.ToList(); } }优点一次查询把所有需要的数据都拿到性能好。缺点得提前知道要加载哪些导航属性。划重点Include就是“带上明细”ThenInclude就是“再带上明细下面的条件”。EF Core 的写法更直观EF6 稍微别扭点但也能用。方案三用 DTO 投影最专业不直接返回实体而是建一个数据传输对象DTO只放你需要返回的字段。查询的时候直接投影彻底绕过导航属性。public class VoucherRuleMasterDto { public int Id { get; set; } public string BusinessType { get; set; } public ListVoucherRuleDetailDto Details { get; set; } } public static ListVoucherRuleMasterDto GetVoucherRuleMasters(string name) { using (var db new PcbEntities()) { var query db.fin_voucher_rule_master.AsNoTracking(); if (!string.IsNullOrEmpty(name)) query query.Where(x x.business_type.Contains(name)); return query.Select(m new VoucherRuleMasterDto { Id m.Id, BusinessType m.business_type, Details m.fin_voucher_rule_detail.Select(d new VoucherRuleDetailDto { Id d.Id, Condition d.fin_voucher_rule_condition.Description }).ToList() }).ToList(); } }优点只返回前端真正需要的数据网络传输量小。彻底解耦数据库模型和 API 接口。再也不用担心延迟加载和序列化问题。缺点多写几个 DTO 类可以用 AutoMapper 偷懒。划重点DTO 方案是最“正统”的做法推荐在正式项目里用。实体是给数据库用的DTO 是给前端用的别混在一起。四、EF6 和 EF Core 的 Include/ThenInclude 区别一张表看懂很多从 EF6 转到 EF Core 的兄弟会被ThenInclude搞晕。刚子给你总结一下你要加载什么EF6 写法EF Core 写法单个导航属性如 Detail.Include(x x.Detail)或Include(Detail).Include(x x.Detail)嵌套属性Detail.Condition.Include(x x.Detail.Condition)或Include(Detail.Condition).Include(x x.Detail).ThenInclude(d d.Condition)集合的嵌套属性Details里的Condition.Include(x x.Details.Select(d d.Condition)).Include(x x.Details).ThenInclude(d d.Condition)常见坑编译错误Include does not contain a definition for ThenInclude→ 说明你用的是 EF6别用ThenInclude。运行时InvalidOperationException: A second operation started on this context before a previous operation completed→ 你在遍历结果时又触发了延迟加载关掉它或者提前Include。五、最佳实践总结照着做不踩坑Web 应用全局关闭延迟加载在DbContext构造函数里加上public PcbEntities() { this.Configuration.LazyLoadingEnabled false; // EF6 // 或 this.ChangeTracker.LazyLoadingEnabled false; // EF Core }需要关联数据的地方手动Include。只读查询一律用AsNoTracking()提升性能减少内存占用。别在using块外面访问导航属性要么提前Include要么把序列化操作放在using里面。优先用 DTO 投影这是最干净、最专业的做法。搞清楚你的 EF 版本看packages.config或.csprojEntityFramework6.x → EF6Microsoft.EntityFrameworkCore→ EF Core六、完整示例拿来即用以下是一个兼容 EF6 和 EF Core 的写法通过条件编译public static Listfin_voucher_rule_master GetFin_Voucher_Rule_Masters(string name) { using (var db new PcbEntities()) { // 关闭延迟加载 db.Configuration.LazyLoadingEnabled false; var q db.fin_voucher_rule_master.AsNoTracking(); // 预先加载三层数据 #if EF6 q q.Include(fin_voucher_rule_detail.fin_voucher_rule_condition); #else q q.Include(m m.fin_voucher_rule_detail) .ThenInclude(d d.fin_voucher_rule_condition); #endif if (!string.IsNullOrEmpty(name)) q q.Where(x x.business_type.Contains(name)); return q.ToList(); } }最后刚子想说ObjectDisposedException这个错基本每个用 EF 的人都遇到过。搞懂了延迟加载的原理解决起来其实很简单。记住一句话在 DbContext 还活着的时候把你需要的数据全都显式加载好。如果你觉得这篇文章帮你搞明白了点个赞、转给还在被 EF 坑的兄弟。

相关新闻

AI的原理科普:人工智能究竟是如何“思考”的?

AI的原理科普:人工智能究竟是如何“思考”的?

AI的原理科普:人工智能究竟是如何“思考”的?引言:AI真的会思考吗?近年来,ChatGPT、DeepSeek、通义千问、豆包、Kimi等人工智能产品迅速普及,很多人都会产生一个疑问:AI到底是怎么工作的&#x…

2026/7/24 0:07:12 阅读更多 →
六轴机械臂改进混沌麻雀(ISSA)与粒子群算法(PSO)最优时间353轨迹规划对比

六轴机械臂改进混沌麻雀(ISSA)与粒子群算法(PSO)最优时间353轨迹规划对比

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/7/23 9:49:17 阅读更多 →
YOLOv11训练中的AutoAnchor自动锚框计算:何时用、何时不用?

YOLOv11训练中的AutoAnchor自动锚框计算:何时用、何时不用?

别再无脑开启--anchor-tune了!90%的人用错了自动锚框 引言:一个让无数人翻车的参数 先讲一个真实案例。 上个月,一位读者在后台私信我:“用YOLOv11s训练工业零件检测数据集,COCO预训练权重下mAP50有0.52,换到自己的数据集上直接掉到0.31。” 排查了两天,最后发现罪魁祸…

2026/7/25 2:56:14 阅读更多 →

最新新闻

晚风棱镜数字权益深耕虚拟商品赛道

晚风棱镜数字权益深耕虚拟商品赛道

数字生活全面渗透当下,影音会员、游戏点券、生活卡券、数字素材、软件授权等虚拟商品,早已成为大众日常消费、企业营销运营的刚需。传统综合电商虚拟品类分散、货源杂乱、交易安全缺乏保障,垂直数字权益交易市场长期存在效率、合规、售后多重…

2026/7/27 8:49:07 阅读更多 →
遇到格式报错别慌!AI 导出鸭全方位处理:Claude 公式粘贴后乱码怎么解决?多工具对比方案汇总

遇到格式报错别慌!AI 导出鸭全方位处理:Claude 公式粘贴后乱码怎么解决?多工具对比方案汇总

AI 导出鸭实操指南:Claude公式粘贴后乱码怎么解决?多渠道导出格式错乱问题一站式修复教程遇到格式报错别慌!AI 导出鸭全方位处理:Claude公式粘贴后乱码怎么解决?多工具对比方案汇总AI 导出鸭专业格式转换工具&#xff…

2026/7/27 8:49:07 阅读更多 →
Claude 文档怎么导出?无需复杂操作,AI 导出鸭全平台适配

Claude 文档怎么导出?无需复杂操作,AI 导出鸭全平台适配

Claude文档怎么导出?AI导出鸭一站式搞定各类导出难题Claude文档怎么导出?对比5种导出方式,AI导出鸭优势突出Claude文档怎么导出?无需复杂操作,AI导出鸭全平台适配 引言 不少日常使用Claude做文案、方案、数据分析的从业…

2026/7/27 8:49:07 阅读更多 →
Jupyter客户端MATLAB语法支持:配置指南与实战应用

Jupyter客户端MATLAB语法支持:配置指南与实战应用

在 Jupyter 中实现客户端 MATLAB 语法支持:完整配置与实战指南 对于数据科学和工程计算领域的开发者来说,MATLAB 和 Jupyter 是两个不可或缺的工具。MATLAB 提供强大的数学计算和可视化能力,而 Jupyter 则以其交互式编程环境著称。但长期以来…

2026/7/27 8:49:07 阅读更多 →
YOLOv11与CSFCN融合的软塑料检测系统开发实践

YOLOv11与CSFCN融合的软塑料检测系统开发实践

1. 项目背景与核心价值在工业质检和环保回收领域,软塑料制品的自动检测一直是个技术难点。传统人工分拣效率低下且成本高昂,而常规的视觉检测方案又难以应对软塑料的复杂特性——形状不规则、表面反光、纹理多变。我们团队基于YOLOv11框架,创…

2026/7/27 8:49:06 阅读更多 →
DSP热设计实战:从热阻解析到PCB散热优化,保障SM320F28335-HT稳定运行

DSP热设计实战:从热阻解析到PCB散热优化,保障SM320F28335-HT稳定运行

1. 项目概述:为什么热设计是DSP稳定性的生命线如果你正在使用TI的SM320F28335-HT这颗高性能DSP,尤其是在工业电机驱动、大功率变频器或者高温环境下的控制系统中,那么你大概率已经或即将遇到一个绕不开的难题:芯片烫手。这颗芯片性…

2026/7/27 8:48:06 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻