news 2026/7/15 5:47:13

突然报 “关键字 WITH 附近有语法错误“?一篇避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
突然报 “关键字 WITH 附近有语法错误“?一篇避坑指南

大家好,我是码农刚子,最近遇到一个EF Core 查询的问题,跟大家分享下。

升级到 .NET 8 / EF Core 8 后,原来跑得好好的Where(x => ids.Contains(x.id))突然炸了,日志里赫然写着:关键字 'WITH' 附近有语法错误。如果此语句是公用表表达式,那么前一个语句必须以分号结尾。——这篇文章帮你搞清楚为什么、怎么修、以后怎么写才不踩坑。

1. 先看症状

假设你有这样一段再普通不过的代码:

var ids = new List<int> { 1, 2, 3, 5, 8 }; var users = await _db.sys_admin .Where(x => ids.Contains(x.id)) .ToListAsync();

在 EF Core 6/7 上完全正常。升级到 EF Core 8 后,同样的代码报:

Microsoft.Data.SqlClient.SqlException (0x80131904): 关键字 'WITH' 附近有语法错误。 如果此语句是公用表表达式、xmlnamespaces 子句或者更改跟踪上下文子句, 那么前一个语句必须以分号结尾。

关键词:WITH分号公用表表达式(CTE)。SQL Server 错误号为 156。

2. 根因:EF Core 8 对 Contains 的翻译方式变了

这不是 Bug,这是 EF Core 8 的一个有意为之的 Breaking Change(官方文档明确定义为 High Impact)。

2.1 旧行为(EF Core 6/7)

EF 把参数化列表的值内联为 SQL 常量

-- EF Core 7 生成的 SQL SELECT [s].[id], [s].[username], ... FROM [sys_admin] AS [s] WHERE [s].[id] IN (1, 2, 3, 5, 8)

简单直接,没有 CTE,没有任何问题——直到你开始关注查询计划缓存。

2.2 新行为(EF Core 8)

EF Core 8 不再内联常量,而是通过OPENJSONCTE(公用表表达式)来传递参数化集合。简化后的生成逻辑是:

简单值列表(string/int 常量)→ OPENJSON 方式 复杂查询 / 多次 Contains → CTE(WITH ... AS)方式

对于ids.Contains(x.id)这类场景,EF 可能生成类似这样的 SQL:

-- EF Core 8 可能生成的 SQL(简化版) ;WITH [t] AS ( SELECT [v].[value] FROM OPENJSON(@__ids_0) ... ) SELECT [s].[id], ... FROM [sys_admin] AS [s] WHERE [s].[id] IN (SELECT [t].[value] FROM [t])

问题来了:WITH前面必须有一个完整语句的分号;。如果当前 SQL 批处理中 EF 没有在前面补上分号,SQL Server 就会报错 156。

2.3 官方文档怎么说

微软在 EF Core 8 Breaking Changes 中明确记录了这条(Tracking Issue #13617):

Containsin LINQ queries may stop working on older SQL Server versions

Impact: High

链接:learn.microsoft.com - Breaking changes in EF Core 8.0

3. 什么时候会触发?

不是所有Contains都会炸,但它会在你不经意间冒出来。触发条件包括但不限于:

场景风险
ids.Contains(x.id)idsList<int>🔴 高
ids.Contains(x.id)idsList<int?>🔴 高(我们项目遇到的)
stringList.Contains(x.name)🟡 中(可能走 OPENJSON)
同一查询中有多个Contains🔴 高
.Contains()嵌套在复杂Where表达式中🟡 中
查询中同时有其他关联(Join / Include)🔴 高

最重要的信号:一旦看到错误信息里出现WITH分号,99% 就是这个问题。

4. 解决方案(5 种,从优到差)

方案一:参数化 Raw SQL(推荐 ⭐)

直接绕过 EF 翻译,用FromSqlRaw+SqlParameter,性能最优,零坑:

var paramNames = ids.Select((_, i) => $"@p{i}").ToArray(); var parameters = ids.Select((id, i) => new Microsoft.Data.SqlClient.SqlParameter($"@p{i}", id)).ToArray(); var sql = $"SELECT * FROM sys_admin WHERE id IN ({string.Join(",", paramNames)})"; var users = await _db.sys_admin .FromSqlRaw(sql, parameters) .ToListAsync();
  • ✅ 生成的 SQL 就是简单的WHERE id IN (@p0, @p1, ...)
  • Microsoft.Data.SqlClient随 EF Core SQL Server 包引入,无需另装
  • ✅ 完全防注入
  • ⚠️ 需要知道表名(但你的 DbContext 本来就定义了)

适用:批量删除、批量更新、批量查询等「已知 ID 列表查实体」场景。

方案二:FindAsync 逐个查询(小数据量 ⭐)

如果 ID 列表很短(比如页面批量操作选 10-20 条),直接用主键查:

var users = new List<sys_admin>(); foreach (var id in ids) { var user = await _db.sys_admin.FindAsync(id); if (user != null) users.Add(user); }
  • FindAsync走主键索引直查,不生成 CTE
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/13 5:12:04

Windows风扇控制终极指南:用Fan Control彻底告别噪音烦恼

Windows风扇控制终极指南&#xff1a;用Fan Control彻底告别噪音烦恼 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending…

作者头像 李华
网站建设 2026/7/13 16:25:34

从FIR与IIR的群延迟差异,看滤波器如何塑造信号

1. 为什么群延迟是滤波器设计的命门&#xff1f; 我第一次用IIR滤波器处理心电图信号时&#xff0c;发现QRS波群竟然出现了奇怪的变形&#xff0c;R波峰值位置偏移了15ms。这个教训让我明白&#xff1a;群延迟特性直接决定了信号的时间保真度。想象你在玩"传话游戏"&…

作者头像 李华
网站建设 2026/7/12 15:18:24

nlohmann/json:现代C++ JSON处理的终极完整指南

nlohmann/json&#xff1a;现代C JSON处理的终极完整指南 【免费下载链接】json JSON for Modern C 项目地址: https://gitcode.com/GitHub_Trending/js/json nlohmann/json是C开发者处理JSON数据的首选库&#xff0c;提供零依赖的单头文件解决方案&#xff0c;完美支持…

作者头像 李华
网站建设 2026/7/12 14:18:10

RSA非对称加密在登录模块的实战应用:从原理到前后端完整实现

1. 项目概述与核心价值最近在做一个后台管理系统的重构&#xff0c;登录模块的安全性是甲方和测试同学反复强调的重点。传统的“用户名密码”明文传输或者简单MD5一下&#xff0c;在现在这个网络环境下&#xff0c;基本等于“裸奔”。稍微有点安全意识的人&#xff0c;都会想到…

作者头像 李华
网站建设 2026/7/12 9:05:24

TPIC7710EVM评估板实战:从硬件解析到GUI软件驱动的电机控制芯片验证

1. 项目概述与EVM核心价值在嵌入式系统&#xff0c;尤其是汽车电子和工业控制这类对可靠性要求极高的领域&#xff0c;工程师在选定一颗核心芯片后&#xff0c;面临的首要挑战往往不是写代码&#xff0c;而是如何快速、准确地验证这颗芯片在实际电路中的表现。数据手册上的参数…

作者头像 李华