LINQ to Entities识别get_Item失败及Session传值空引用问题求解
问题根因
- 第一个LINQ报错:LINQ to Entities会将查询表达式翻译为SQL语句在数据库端执行,你直接在Where lambda中写
(int)Session["HospitalId"],本质是调用Session索引器的get_Item方法,该方法无法被EF翻译为SQL表达式,因此抛出异常。 - 第二个空引用报错:你将Session值提前赋值为局部变量的思路是对的,但此时
Session["HospitalId"]本身为null——你通过ActionLink传递的hospitalId是路由参数,并没有被存入Session,直接将null强转为int类型就会触发空引用异常。
完整修复方案
1. 接收路由参数并存入Session
你当前Samples控制器的Index动作没有声明接收路由传过来的hospitalId参数,首先修改Index动作,增加参数接收、合法性校验逻辑,校验通过后将值存入Session:
public ActionResult Index(int? hospitalId) { // 优先处理本次请求携带的合法hospitalId参数 if (hospitalId.HasValue && hospitalId.Value > 0) { Session["HospitalId"] = hospitalId.Value; } // 没有携带新参数时,校验Session中是否已有历史存储值 else if (Session["HospitalId"] == null) { // 无有效参数时跳转至入口页面,避免后续逻辑报错 return RedirectToAction("Index", "Home"); } int[] exclude = { 13, 14, 15 }; var samples = _context.samples.Where(m => !exclude.Contains(m.id)).ToList(); return View(samples); }
2. 修复Results动作的查询与校验逻辑
在Results动作中先完成Session值的非空校验、类型转换,再使用提前赋值的局部变量执行LINQ查询:
public ActionResult Results() { // 先校验Session值有效性,避免空引用、类型转换错误 if (Session["HospitalId"] == null || !int.TryParse(Session["HospitalId"].ToString(), out int hospitalId)) { return RedirectToAction("Index", "Samples"); } // 使用C#侧提前赋值的值类型变量做查询,EF可正常翻译为SQL var samples = _context.RESULTS.Where(s => s.status == 2 && s.custid == hospitalId).ToList(); return View(samples); }
开发注意事项
- 禁止在LINQ to Entities查询表达式内直接调用无法翻译为SQL的方法,包括Session/Request的索引器、自定义C#函数等,这类值必须提前在C#内存中读取、转换为基础类型局部变量后,再传入查询表达式。
- 所有Session取值必须做非空和类型校验:Session存在过期机制,且不是所有请求路径都会提前写入目标Session值,直接强转值类型极易触发运行时异常。
- 路由参数仅在当前请求的目标动作中可直接获取,跨动作使用时必须通过Session、TempData存储,或在跳转链接/表单中持续透传。
内容的提问来源于stack exchange,提问作者MarwanAbu
相关产品推荐
相关产品推荐

