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

访问@Model.Product.category.Name报Object Context实例已释放错误如何解决

问题根因

这个报错是Entity Framework的懒加载机制和上下文生命周期不匹配导致的:
你的Product实体中category导航属性加了virtual关键字,启用了懒加载,只有当你第一次访问这个属性的时候EF才会去数据库查询关联的Category数据。而你查询Product的DbContext在控制器返回视图之前就已经被释放了(不管是用using块手动释放,还是依赖注入的Scoped生命周期到控制器结束就销毁),等到视图渲染执行@Model.Product.category.Name触发懒加载时,已经没有可用的数据库连接了,就会抛出这个错误。

解决方案
  • 方案1:预先加载关联数据(最常用)
    在控制器查询Product的时候,用Include方法指定提前加载category导航属性,避免后续触发懒加载。
    示例代码:

    // 注意先引用命名空间 using System.Data.Entity;
    var product = dbContext.Products
                  .Include(p => p.category) // 提前加载关联的category
                  .FirstOrDefault(p => p.Id == yourProductId);
    

    这样查询Product的时候会一次性把关联的Category数据查出来,后续访问category属性就不会触发新的数据库查询。

  • 方案2:调整视图模型,提前映射需要的字段(最佳实践)
    不要在视图层直接访问实体的导航属性,把需要用到的字段提前填充到视图模型中,从根源上避免视图层触发数据库操作。
    修改视图模型:

    public class ProductViewModel
    {
        public Product Product { get; set; }
        // 新增需要的分类名字段
        public string CategoryName { get; set; }
    }
    

    控制器中赋值:

    var viewModel = new ProductViewModel
    {
        Product = product,
        CategoryName = product.category.Name // 上下文还没释放的时候就完成赋值
    };
    

    视图直接使用提前赋值好的字段:

    <a href="#">@Model.CategoryName</a>
    
  • 方案3:显式声明外键属性(可选补充)
    你代码中注释掉的CategoryID外键字段可以恢复,显式声明外键可以让EF的关联处理更稳定,也方便你在不需要加载整个Category实体的时候直接获取外键值:

    public class Product:BaseEntity
    {
        public decimal price { get; set; }
        public int CategoryID { get; set; } // 恢复外键字段
        public string ImageURL { get; set; }
        public virtual Category category { get; set; }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:36:03