使用FromSqlRaw查询数据时AsEnumerable不生效,EF Core搜索报错如何解决
问题修复方案
核心原因
你遇到的两类报错本质是两个常见的EF Core使用误区:
- 直接用
FromSqlRaw("dbo.spStaysSearch")调用存储过程时,未加EXEC前缀,EF Core会将存储过程名误判为表名,后续拼接的LINQ过滤、排序操作无法生成合法SQL,导致运行时错误,也就是你用AsQueryable时页面无数据的原因。 - 提前转
AsEnumerable后,查询逻辑会从数据库端转移到内存执行,同时IEnumerable类型不支持EF Core提供的CountAsync、ForEachAsync等异步扩展方法,因此触发智能感知报错。
具体修复步骤
步骤1:修正存储过程调用语法
修改getSearchData方法中FromSqlRaw的写法,补充EXEC前缀,同时添加AsNoTracking优化只读查询性能:
var records = db.SpStaySearches.FromSqlRaw("EXEC dbo.spStaysSearch").AsNoTracking();
你原来代码里的.AsQueryable()可以省略,FromSqlRaw返回的结果本身就是IQueryable类型。
步骤2:确认动态排序依赖包
你使用的字符串参数OrderBy方法是System.Linq.Dynamic.Core包提供的扩展功能,请确认你的项目已经安装该NuGet包,否则会触发编译错误。
步骤3:优化查询执行逻辑
不要提前将IQueryable转为IEnumerable,所有过滤、排序、计数、分页操作都保留在IQueryable阶段执行,由EF Core翻译成SQL在数据库端运行,性能更高。将原来的ForEachAsync逻辑替换为更稳定的ToListAsync+手动映射:
// 原来的try块替换为以下代码 try { // 分页后的查询结果一次性加载到内存 var queryResult = await records.ToListAsync().ConfigureAwait(false); foreach (var r in queryResult) { result.Add(new SpStaySearchResultViewModel() { BuildingName = r.BuildingName, CaseManager = r.CaseManager, CaseManagerId = r.CaseManagerId, OccupantFileAs = r.OccupantFileAs, StayOCFSNumber = r.StayOCFSNumber, StayId = r.StayId, MaxOfBillSentDate = r.MaxOfBillSentDate, CountOfChildren = r.CountOfChildren, StartDate = r.StartDate, EndDate = r.EndDate, OccupantId = r.OccupantId, IsActive = r.IsActive, }); } } catch (Exception e) { // 建议此处补充日志逻辑,避免异常被吞导致问题难以排查 }
可选优化
你现有代码中BuildingName的过滤条件重复写了两次,可以删除其中一处冗余逻辑。
内容的提问来源于stack exchange,提问作者Masterolu
相关产品推荐
相关产品推荐

