假设你有这样一段再普通不过的代码:
var ids new List { 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。根因EF Core 8 对 Contains 的翻译方式变了这不是 Bug这是 EF Core 8 的一个 有意为之的 Breaking Change官方文档明确定义为 High Impact。2.1 旧行为EF Core 6/7EF 把参数化列表的值内联为 SQL 常量– EF Core 7 生成的 SQLSELECT [s].[id], [s].[username], …FROM [sys_admin] AS [s]WHERE [s].[id] IN (1, 2, 3, 5, 8)简单直接没有 CTE没有任何问题——直到你开始关注查询计划缓存。2.2 新行为EF Core 8EF Core 8 不再内联常量而是通过 OPENJSON 或 CTE公用表表达式 来传递参数化集合。简化后的生成逻辑是简单值列表string/int 常量→ OPENJSON 方式复杂查询 / 多次 Contains → CTEWITH … 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 #13617Contains in LINQ queries may stop working on older SQL Server versionsImpact: High链接learn.microsoft.com - Breaking changes in EF Core 8.0什么时候会触发不是所有 Contains 都会炸但它会在你不经意间冒出来。触发条件包括但不限于场景 风险ids.Contains(x.id) 且 ids 是 List 高ids.Contains(x.id) 且 ids 是 Listint? 高我们项目遇到的stringList.Contains(x.name) 中可能走 OPENJSON同一查询中有多个 Contains 高.Contains() 嵌套在复杂 Where 表达式中 中查询中同时有其他关联Join / Include 高最重要的信号一旦看到错误信息里出现 WITH 和 分号99% 就是这个问题。解决方案5 种从优到差方案一参数化 Raw SQL推荐 ⭐直接绕过 EF 翻译用 FromSqlRaw SqlParameter性能最优零坑var paramNames ids.Select((_, i) pi).ToArray();varparametersids.Select((id,i)newMicrosoft.Data.SqlClient.SqlParameter(p{i}).ToArray(); var parameters ids.Select((id, i) new Microsoft.Data.SqlClient.SqlParameter(pi).ToArray();varparametersids.Select((id,i)newMicrosoft.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 Listsys_admin();foreach (var id in ids){var user await _db.sys_admin.FindAsync(id);if (user ! null) users.Add(user);}✅ FindAsync 走主键索引直查不生成 CTE✅ 简单可靠❌ N1 查询ID 数量多时性能差适用后台管理的批量操作用户勾选几条记录删除/启用等ID 数量通常不超过几十个。方案三全量拉到内存过滤小表 ⭐var all await _db.sys_admin.ToListAsync();var users all.Where(x ids.Contains(x.id)).ToList();✅ 零 SQL 风险✅ 一句话搞定❌ 全表拉到内存表大了就是灾难❌ Contains 在内存中走 LINQ to Objects没有 SQL 问题适用字典表、配置表等行数很少1000的表。方案四ToArray()碰运气有时候 List 换成 int[] 后EF 生成的 SQL 就不同了var idArray ids.ToArray();var users await _db.sys_admin.Where(x idArray.Contains(x.id)).ToListAsync();⚠️ 不保证有效取决于具体的 EF Core 8.x 小版本和查询复杂度⚠️ 同一套代码在不同环境可能表现不一致❌ 不推荐作为可靠方案方案五EF 9 专属TranslateParameterizedCollectionsToConstants如果你已经升级到 EF Core 9可以用新增的配置项恢复旧行为protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){optionsBuilder.UseSqlServer(connectionString).TranslateParameterizedCollectionsToConstants();}或者builder.Services.AddDbContext(options options.UseSqlServer(connectionString,sqlOptions sqlOptions.TranslateParameterizedCollectionsToConstants()));✅ 全局生效一行配置解决✅ 恢复 EF Core 7 的 Contains 翻译方式❌ 回到旧行为查询计划缓存问题依旧存在微软当初改它的原因❌ 需要 EF Core 95. 推荐策略你的 SQL Server 版本 2016 且兼容级别 130└─ 是 → 方案一FromSqlRaw或方案二FindAsync保持 EF8 的新行为└─ 否 → 考虑升级 SQL Server 或兼容级别你的项目还在 .NET 8 / EF Core 8└─ 批量操作已知 IDs→ 方案一 或 方案二└─ 动态查询用户输入过滤→ 直接用 EF8 的 OPENJSON 方式不会触发 CTE 问题└─ 小表兜底 → 方案三你的项目已升级到 EF Core 9└─ 考虑方案五但要理解它的代价查询计划缓存退化6. 实战案例MiePcb 项目经验我们在 MiePcb 管理后台项目中先后踩了两次这个坑踩坑 1GetPageList 的部门查询// 错误写法query query.Where(x deptIds.Contains(x.dept_id));报错WITH 附近语法错误。修复内存全量拉取部门表再 Join 过滤。var depts await _db.sys_dept.Select(d new { d.id, d.name }).ToListAsync();// 后续在内存中关联踩坑 2BatchDelete 的批量删除// 错误写法var users await _db.sys_admin.Where(x ids.Contains(x.id)).ToListAsync();报错同上。修复方案一FromSqlRaw 参数化一次查询干净利落。经验总结EF Core 8 的项目所有 Contains 都要在心里打个问号 — 写的时候就要想好万一报错走哪个方案Listint? 比 List 更容易触发 — 可空类型让 EF 生成的 SQL 更复杂更倾向 CTESQL Server 错误 156 看到 WITH 就看 Contains — 排查方向比错误信息本身更重要记录到 MEMORY.md — 团队其他人可能不知道这个坑要有文档沉

相关新闻

TrollInstallerX深度解析:iOS越狱应用安装的终极技术实现

TrollInstallerX深度解析:iOS越狱应用安装的终极技术实现

TrollInstallerX深度解析:iOS越狱应用安装的终极技术实现 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX TrollInstallerX是一款专为iOS 14.0到16.6.1系统设…

2026/7/10 7:06:12阅读更多 →
从课堂到全球舞台:MGBX以教育生态连接下一代Web3创新力量

从课堂到全球舞台:MGBX以教育生态连接下一代Web3创新力量

当数字经济逐渐成为全球发展的重要驱动力,关于区块链、人工智能、数字资产以及Web3的讨论,正在从行业内部走向更广泛的社会层面。过去几年,数字资产行业的发展更多集中在技术创新与市场建设,而如今,人才培养和知识普及…

2026/7/10 7:06:12阅读更多 →
节省Token的方案-现在 GitHub 上比较成型的开源方案,重点看“上下文压缩、仓库索引/RAG、代码库摘要、AI 规则/记忆管理”这几类

节省Token的方案-现在 GitHub 上比较成型的开源方案,重点看“上下文压缩、仓库索引/RAG、代码库摘要、AI 规则/记忆管理”这几类

节省Token的方案-现在 GitHub 上比较成型的开源方案,重点看“上下文压缩、仓库索引/RAG、代码库摘要、AI 规则/记忆管理”这几类 截至 2026-07-09,我会把开源方案分成 4 类: 最适合直接配 Cursor:Serena MCP GitHub: oraios/seren…

2026/7/10 7:06:12阅读更多 →
2026 工业数字化碳排放管理平台服务商精选榜

2026 工业数字化碳排放管理平台服务商精选榜

2026 年,国内工业数字化、绿色低碳转型进入全面落地、从严监管新阶段。全国碳排放核查范围持续扩容,能耗双控全面转向碳排放双控,绿色工厂、零碳园区评审标准持续更新,ESG 信息披露逐步走向常态化强制披露。各类生产企业、产业园区…

2026/7/10 8:26:17阅读更多 →
Godot 4.3与Zig 0.13集成指南:构建高性能游戏扩展

Godot 4.3与Zig 0.13集成指南:构建高性能游戏扩展

1. 项目概述:当Godot遇见Zig如果你是一个对游戏开发充满热情,同时又对现代系统级编程语言Zig抱有好奇心的开发者,那么“Godot-Zig”这个项目绝对值得你投入时间研究。简单来说,它是一个为Godot 4引擎提供Zig语言绑定的开源库。这意…

2026/7/10 8:26:17阅读更多 →
2026免费投票系统深度测评,好用稳定平台结果展示

2026免费投票系统深度测评,好用稳定平台结果展示

办一场线上投票,选对工具能让活动事半功倍,选错工具则可能陷入“数据导不出、页面全是广告、票数被刷崩”的困境。2026年市面上号称“免费”的投票平台不少,但真正能做到永久免费、强防刷、高稳定、零广告的,其实就那么几款。本文…

2026/7/10 8:26:17阅读更多 →
51单片机电子时钟设计:汇编与C语言实现LCD1602驱动的3点关键差异

51单片机电子时钟设计:汇编与C语言实现LCD1602驱动的3点关键差异

51单片机电子时钟设计:汇编与C语言实现LCD1602驱动的3点关键差异 1. 开发效率与可维护性对比 在51单片机项目中,选择汇编还是C语言往往成为开发者面临的第一个决策难题。让我们从一个真实场景开始:当你需要修改LCD1602的初始化参数时&#x…

2026/7/10 8:26:16阅读更多 →
AI 时代的内在竞技场:当情绪清晰度成为最后的护城河

AI 时代的内在竞技场:当情绪清晰度成为最后的护城河

AI 时代的内在竞技场:当情绪清晰度成为最后的护城河 摘要:AI 正在商品化知识与努力。OpenAI 教练 Joe Hudson 提出"智慧栈"框架,指出情绪清晰度才是后 AGI 时代真正的竞争优势。 一个让人不安的问题 如果 AI 能在几秒钟内完成你一…

2026/7/10 8:26:16阅读更多 →
亲密关系中的隐性权力:藏在日常相处里的不对等

亲密关系中的隐性权力:藏在日常相处里的不对等

看到一位博主分享了一个很诚实的观察:当她站到资源掌控者的位置上,第一感受不是愧疚,而是强烈的爽感。她说自己是个有性别平等意识、会主动反思的人,但当她拥有更多资源的时候,她依然会被那种 “我说了算” 的感觉裹挟…

2026/7/10 8:21:16阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/9 5:56:19阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/9 9:45:20阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/10 4:59:05阅读更多 →
浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比当你在浏览器地址栏敲入一个网址时,背后可能隐藏着一场关于"要不要重新下载资源"的精密博弈。这场博弈的裁判是HTTP缓存机制,而304状态码则是这场博弈…

2026/7/10 0:00:01阅读更多 →
RoboWits:面向创造性问题求解的双臂机器人认知推理基准

RoboWits:面向创造性问题求解的双臂机器人认知推理基准

1. 项目概述:这不是又一个机器人抓取数据集,而是一次对“思考力”的压力测试 RoboWits——这个名字里藏着两个关键信号:“Robo”直指物理世界中的具身智能体,“Wits”则毫不掩饰地指向人类最核心的认知能力:机敏、判断…

2026/7/10 0:00:01阅读更多 →
5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款专为Windows…

2026/7/10 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/9 9:45:20阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/9 15:50:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/9 14:14:17阅读更多 →