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

EF调用FromSql获取实体后用Linq的Any方法过滤报错如何解决

问题原因

你当前使用的是EF Core 1.x版本(对应dnx4.5.1、VS2015的运行环境),该版本对FromSql返回的IQueryable嵌套在Linq查询中的支持存在缺陷:

  • 你代码里的listAeGrp和_orders都是未实际执行的IQueryable对象,没有加载到内存
  • 当你把listAeGrp.Any(...)写入_orders的Where条件时,EF Core会尝试把整个表达式翻译成SQL语句,但旧版本无法识别FromSql的重载,直接抛出解析错误。
实现需求的替代方案

方案1:提前加载过滤用的AE列表到内存(改动最小,适配当前环境)

listAeGrp是根据用户ID查询的小数据集,你可以先把它从数据库加载到内存,再用内存集合过滤订单查询,不需要EF解析嵌套的FromSql,修改后的代码如下:

[HttpGet]
public async Task<IActionResult> GetViewIO()
{
    int uid = (int)HttpContext.Session.GetInt32("userId").Value;

    if(uid == 2)
    {
        uid = 33;
    }

    // 加ToListAsync()提前把AE列表加载到内存,变成普通List集合
    var listAeGrp = await _context.ListofAE.FromSql($"Execute ListOfAe {uid}").ToListAsync();
    // 提前提取所有AE的id,后续过滤性能更高
    var aeIdList = listAeGrp.Select(y => y.id).ToList();
    var _orders = _context.OrderHeaderView.FromSql(@"OrderHeaderView").OrderByDescending(f => f.id).OrderBy(p => p.platform_id);

    // 用内存的aeIdList做Contains判断,EF可以把这个翻译成SQL的IN语句,不会报错
    var orders = await _orders.Where(x => aeIdList.Contains(x.created_by)).ToListAsync();
    
    return Json(orders);
}

方案2:合并存储过程逻辑

如果订单数据量极大,不想在SQL中使用IN条件,可以直接把AE过滤的逻辑写到订单的存储过程里,一次查询直接返回过滤后的订单结果,不需要应用层做两次查询再过滤,性能更高。

补充说明:如果后续你将EF Core升级到2.0及以上版本,对FromSql的嵌套查询支持会完善很多,但当前版本环境下优先使用方案1即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:06:03