System.Data.SqlClient.SqlException (0x80131904): 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。

问题:System.Data.SqlClient.SqlException (0x80131904): 'OFFSET' 附近有语法错误。在 FETCH 语句中选项 NEXT 的用法无效。

使用ef core做分页查询的时候遇到这个问题,后来发现问题是出在数据库上面,测试的时候用的数据库是2016的,没有出现上述问题,但是发布到正式环境(sql server 2008 )后问题就出现。

解决方法:

在startup中添加dbcontext的时候,添加一个额外的参数:

options.UseSqlServer(Configuration.GetConnectionString("Test_ExamAffair"),b=>b.UseRowNumberForPaging());

如果是ef不是ef core ,解决方法不一样(我没有测试过):

1、首先找到edmx文件。
        2、把下面的2012的值替换为2008即可。
             ProviderManifestToken=“2012” ==> ProviderManifestToken=“2008”

这样问题就解决啦!我们看一下两种写法生成的sql语句:

SELECT [x].*
FROM [Exam] AS [x]
WHERE [x].[IsRelease] = 1
ORDER BY [x].[InTime] DESC
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY

添加上述的参数后:

SELECT [t].* FROM (
    SELECT [x].*, ROW_NUMBER() OVER(ORDER BY [x].[InTime] DESC) AS [__RowNumber__]
    FROM [Exam] AS [x]
    WHERE [x].[IsRelease] = 1
) AS [t]
WHERE ([t].[__RowNumber__] > 10) AND ([t].[__RowNumber__] <=20)

归根结底,问题的错误原因在于 老版本数据库不支持 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY 语法。

另外:我们用ef分页的时候,千万不要把符合条件的数据都查询出来再做分页!在ToList()或其他会触发查询的方法前使用skip和Take,取出一页数据,否则会很吃内存。但是这样就必须要两次数据库查询,一次查数据,另外一次查总条数。

发布了31 篇原创文章 · 获赞 56 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/maaici/article/details/104059347