单元测试中如何Shim Enumerable.Cast?EF表达式转换报错求解
问题解决方法
先修复EF表达式的根本问题
你当前的代码里用new List<string>().Cast<double>()存在两个核心问题:
- EF无法将内存集合的
Cast操作翻译成对应SQL,执行时会引发转换错误; string直接强制Cast<double>本身不安全,当字符串无法转成double时必然报错。
替换成EF可翻译的安全转换写法,二选一即可:
方法一:使用double.TryParse(EF Core 3.0+支持)
query .Select(item => new { DoubleValue = double.TryParse(item.AdmissionTicketCode, out var val) ? val : (double?)null }) .ToList();
方法二:使用Convert.ToDouble兼容更多EF版本
query .Select(item => new { DoubleValue = item.AdmissionTicketCode != null ? Convert.ToDouble(item.AdmissionTicketCode) : (double?)null }) .ToList();
关于System.Linq.Fakes的ShimEnumerable问题
ShimEnumerable并不存在于System.Linq.Fakes中,因为LINQ的Enumerable类大多是扩展方法,无法通过Fakes进行Shim操作。而且这个思路属于绕远路——只要修复了表达式本身的错误,单元测试不需要依赖Fakes就能正常执行。
单元测试的替代隔离方案
如果需要彻底隔离EF进行单元测试,直接用内存集合模拟查询源即可:
// 模拟测试数据 var testEntities = new List<YourEntityType> { new YourEntityType { AdmissionTicketCode = "678.90" }, new YourEntityType { AdmissionTicketCode = "invalid" } // 测试无效转换场景 }; var query = testEntities.AsQueryable(); // 执行修正后的查询逻辑 var result = query.Select(...).ToList();
内容的提问来源于stack exchange,提问作者Bluck Huang
相关产品推荐
相关产品推荐

