.NET Core 2.1迁移到5.0后LINQ表达式无法转换报错如何解决?
问题解决方法
报错原因
EF Core从3.0版本开始调整了查询翻译规则,禁止未显式声明的客户端计算:2.1版本中LINQ无法翻译成SQL的部分会自动放到内存执行,升级到5.0后这部分逻辑会直接抛出翻译异常,你遇到的问题就是Convert.ToInt32(X.Value)和ToString()的组合逻辑无法被EF Core直接翻译成SQL导致的。
解决方案
方案1:最小改动,显式开启客户端计算
适合部门数据量较小的场景,只需要在投影之后、排序之前加AsEnumerable(),显式告诉EF Core后续逻辑放到内存执行即可:
public List<SelectListItem> GetDepartmentCode() { var table = new List<SelectListItem>(); try { table = (from eb in _context.EbDepartmentMsts select new SelectListItem { Text = string.Concat(eb.DeptCode.ToString(), "~", eb.Description), Value = eb.DeptCode.ToString() }) // 显式将数据加载到内存,后续排序在客户端执行 .AsEnumerable() .OrderBy(X => Convert.ToInt32(X.Value)) .ToList(); } catch(Exception ex) { // 可根据业务需要补充异常日志、兜底逻辑 } return table; }
方案2:数据库端排序(推荐)
适合数据量较大的场景,直接把排序逻辑提前到数据库查询阶段,EF Core可以直接把Convert.ToInt32(eb.DeptCode)翻译成SQL的CAST/CONVERT函数,不需要加载全量数据到内存再排序,性能更好:
public List<SelectListItem> GetDepartmentCode() { var table = new List<SelectListItem>(); try { table = (from eb in _context.EbDepartmentMsts // 排序逻辑提前到数据库层执行,EF可正常翻译 orderby Convert.ToInt32(eb.DeptCode) select new SelectListItem { Text = string.Concat(eb.DeptCode.ToString(), "~", eb.Description), Value = eb.DeptCode.ToString() }) .ToList(); } catch(Exception ex) { // 可根据业务需要补充异常日志、兜底逻辑 } return table; }
注意事项
如果DeptCode字段本身就是数值类型,直接转int即可,不需要多余的ToString()调用;如果是字符串类型,只要字段存储的内容都是合法数字,两种方案都可以正常执行,排序结果和原有逻辑完全一致。
内容的提问来源于stack exchange,提问作者vwadhwa3
相关产品推荐
相关产品推荐

