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

ASP.NET MVC使用Entity Framework返回模型时触发ObjectDisposedException如何解决

根本原因

你遇到的ObjectDisposedException是Entity Framework懒加载触发的典型问题:

  • 你用using块包裹了EF上下文,查询完执行ToList()后,返回Json结果时ASP.NET MVC需要序列化tblDeskBooking实体对象
  • 若tblDeskBooking实体存在导航属性(比如关联的工位表、用户表等关联字段),EF默认开启懒加载,序列化时访问导航属性会触发额外查询,此时上下文已经被using块释放,就会抛出对象已释放的异常。
解决方案

方案1:临时关闭当前查询的懒加载

如果不需要返回关联的导航属性数据,可以在查询前关闭当前上下文的懒加载开关:

[HttpPost]
[Route("DeskBooking")]
public JsonResult DeskBooking(string dpStart, string dpEnd, int tmStart, int tmEnd)
{
    DateTime dpStartCon = DateTime.Parse(GetDateStart(dpStart));
    DateTime dpEndCon = DateTime.Parse(GetDateEnd(dpEnd));
        
    using (Models.nhsdmsEntities ctx = new Models.nhsdmsEntities())
    {
        // 新增这行关闭当前上下文的懒加载
        ctx.Configuration.LazyLoadingEnabled = false;
        List<Models.tblDeskBooking> tblDB = ctx.tblDeskBookings
                                               .Where(x => dpStartCon <= x.DateStart && 
                                                           x.DateEnd <= dpEndCon && 
                                                            tmStart >= x.TimeStart && 
                                                            tmEnd <= x.TimeEnd).ToList();
        return Json(new { data = tblDB }, JsonRequestBehavior.AllowGet);
    }
}

方案2:使用DTO传输数据(更规范的生产环境方案)

定义仅包含前端需要字段的DTO(数据传输对象),查询时直接投影到DTO,避免序列化整个EF实体,从根源上避免懒加载触发:

  1. 首先定义DTO类
public class DeskBookingDto
{
    // 仅保留前端需要的字段,不要添加导航属性
    public int BookingId { get; set; }
    public DateTime DateStart { get; set; }
    public DateTime DateEnd { get; set; }
    public int TimeStart { get; set; }
    public int TimeEnd { get; set; }
    public int DeskId { get; set; }
    // 其他需要返回的字段按需添加
}
  1. 修改接口查询逻辑
using (Models.nhsdmsEntities ctx = new Models.nhsdmsEntities())
{
    var tblDB = ctx.tblDeskBookings
                   .Where(x => dpStartCon <= x.DateStart && 
                               x.DateEnd <= dpEndCon && 
                                tmStart >= x.TimeStart && 
                                tmEnd <= x.TimeEnd)
                   .Select(x => new DeskBookingDto
                   {
                       BookingId = x.Id,
                       DateStart = x.DateStart,
                       DateEnd = x.DateEnd,
                       TimeStart = x.TimeStart,
                       TimeEnd = x.TimeEnd,
                       DeskId = x.DeskId
                       // 其他字段赋值
                   }).ToList();
    return Json(new { data = tblDB }, JsonRequestBehavior.AllowGet);
}

方案3:全局关闭懒加载

如果你的项目所有场景都不需要用到懒加载,可以直接在EF上下文构造函数中全局关闭:

public nhsdmsEntities()
    : base("name=nhsdmsEntities")
{
    // 新增这行全局关闭懒加载
    this.Configuration.LazyLoadingEnabled = false;
}
注意事项
  • 如果确实需要返回关联数据,可使用Include方法提前预加载关联属性,避免序列化时触发懒加载
  • 生产环境不建议直接返回EF实体到前端,既容易引发序列化问题,也会暴露不必要的数据库字段,存在安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:27:01