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

使用Dynamic LINQ的Skip和Take时抛出“Unknown LINQ expression of type Dynamic”异常

在ASP.NET MVC 5.2.9中使用System.Linq.Dynamic.Core 1.2.20实现分页的问题解决办法

问题场景

在ASP.NET MVC(5.2.9)项目中,使用System.Linq.Dynamic.Core(1.2.20)构建报表生成器时,大部分功能正常,但通过SetDynamic方法构建的查询无法使用Skip和Take实现分页,调用这两个方法会抛出异常:Unknown LINQ expression of type 'Dynamic'。移除Skip和Take后查询可正常返回结果,但丢失分页功能。

排查发现,SetDynamic返回IQueryable<object>,而使用强类型的Set<T>开头的相同查询可以正常使用Skip和Take。

原代码示例:

_context.SetDynamic("ENTITY_NAME")
        .Where(_parsingConfig, WHERE_EXPRESSION)
        .OrderBy(_parsingConfig, ORDER_BY_EXPRESSION)
        .Skip(???)// 抛出异常
        .Take(???)// 抛出异常
        .Select(_parsingConfig, SELECT_EXPRESSION)
        .ToDynamicListAsync();

解决方案

方案一:使用Dynamic LINQ的字符串版Skip/Take扩展方法

System.Linq.Dynamic.Core提供了适配动态查询的Skip和Take扩展方法,支持传入字符串形式的表达式参数,替代原生LINQ的Skip(int)和Take(int)。修改代码如下:

// 假设pageIndex是当前页码,pageSize是每页条数
var skipCount = pageSize * (pageIndex - 1);
_context.SetDynamic("ENTITY_NAME")
        .Where(_parsingConfig, WHERE_EXPRESSION)
        .OrderBy(_parsingConfig, ORDER_BY_EXPRESSION)
        .Skip(_parsingConfig, skipCount.ToString())
        .Take(_parsingConfig, pageSize.ToString())
        .Select(_parsingConfig, SELECT_EXPRESSION)
        .ToDynamicListAsync();

如果需要直接引用变量,也可以用Dynamic LINQ的变量引用语法:

_context.SetDynamic("ENTITY_NAME")
        .Where(_parsingConfig, WHERE_EXPRESSION)
        .OrderBy(_parsingConfig, ORDER_BY_EXPRESSION)
        .Skip(_parsingConfig, "@pageSize * (@pageIndex - 1)", new { pageSize, pageIndex })
        .Take(_parsingConfig, "@pageSize", new { pageSize })
        .Select(_parsingConfig, SELECT_EXPRESSION)
        .ToDynamicListAsync();

方案二:转换为IQueryableDynamic后使用原生分页方法

通过AsQueryableDynamic扩展方法,将IQueryable<object>转换为Dynamic LINQ专用的查询类型,这样原生的Skip和Take就能被正确解析:

using System.Linq.Dynamic.Core;

// ...

var dynamicQuery = _context.SetDynamic("ENTITY_NAME")
                           .Where(_parsingConfig, WHERE_EXPRESSION)
                           .OrderBy(_parsingConfig, ORDER_BY_EXPRESSION)
                           .AsQueryableDynamic();

var pagedResult = await dynamicQuery
                   .Skip(pageSize * (pageIndex - 1))
                   .Take(pageSize)
                   .Select(_parsingConfig, SELECT_EXPRESSION)
                   .ToDynamicListAsync();

方案三:内存分页(仅适合小数据量场景)

如果报表数据量不大,业务允许的情况下,可以先查询全量数据,再在内存中执行分页。注意这种方式会加载所有符合条件的数据到内存,大数据量下性能较差:

var fullData = await _context.SetDynamic("ENTITY_NAME")
                             .Where(_parsingConfig, WHERE_EXPRESSION)
                             .OrderBy(_parsingConfig, ORDER_BY_EXPRESSION)
                             .Select(_parsingConfig, SELECT_EXPRESSION)
                             .ToDynamicListAsync();

var pagedData = fullData.Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:25:21