mcpField
Q
query-pipeline

query-pipeline

github.com/dotnet开发14.8k47 次安装今天更新
代码仓库

关于 query-pipeline

用于 Entity Framework Core 查询管线开发的技能,提供查询翻译、优化、拆分查询行为及提供程序级回归测试方面的指导。

主要功能

  1. 01查询回归测试组织
  2. 02翻译回退保护
  3. 03保持 SQL 与 LINQ 语义
  4. 04拆分查询缓冲与一致性
  5. 05SQL 与表达式诊断

适用场景

  1. 01添加由提供程序覆盖的查询回归测试
  2. 02审查查询改写的正确性
  3. 03测试拆分查询终止与一致性行为
  4. 04检查生成的 SQL 和表达式树

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dotnet/efcore --skill query-pipeline

安装后在 Claude Code 中输入/query-pipeline确认已加载。

详细介绍

查询管道

回归测试归属

  • 按内聚的查询或模型特征对查询规范测试分组。不要仅仅因为测试使用自定义模型就创建通用分类;应使用现有的特征专属层级,例如自有实体查询。
  • 放置回归测试前,先检查规范测试基类和各提供程序的重写。将 LINQ 查询、模型设置和结果断言放在共享的虚拟测试中;提供程序重写应调用基类,并且只添加提供程序专属基线或已知限制。
  • 仅针对某个提供程序的测试可能导致其他所有提供程序都未覆盖,即使其 SQL 断言正确也是如此。保留重写保护条件,但不要添加会迫使无关提供程序进行冗余重写的保护条件。
  • 对于优化,应使用精确的结果断言,在同步和异步测试中同时覆盖符合条件和不符合条件的形态。提供具体的提供程序重写和 SQL 基线或已知限制;仅有抽象测试基类或表达式形态检查并不能证明执行覆盖率。

转换

  • 转换回退必须区分已知不支持的形态和意外缺陷。不要将任意异常转化为成功回退。
  • 检查失败的重写是否修改了回退将要复用的状态。对于测试协调,应先确定实际的集合、程序集和异步流边界,再判断共享静态状态是否可能发生竞争;理论测试行并非天然并行,而在 finally 中重置也不具备互斥效果。

优化

  • 根据重写所需的等价性进行匹配,不要盲目依赖表达式相等性。
  • 保留特定上下文中的 null 语义。SQL UNKNOWN 在谓词中可以像 false 一样被筛除,但在投影值中或否定运算下则不行;UseRelationalNulls、包含 null 的 IN/NOT IN,以及标量与复合 LINQ 联接键,都需要不同的补偿方式。
  • 保留基数和运算符顺序,而不只是匹配行。将谓词移过外联接、在 Distinct/GroupBy 中添加键,或将相关 APPLY 转换为 JOIN,都可能改变结果;每个父项的分页必须保留分区和排序,剩余的外部引用必须阻止去相关化。
  • 仅当重复子查询的求值方式和行选择方式等价时才共享它们。易变表达式、在后续导航扩展期间引入的查询筛选器,以及必需导航联接,都可能改变求值次数或限制操作后保留的行。复用前应检查确定性和行保留情况,并在各自的 lambda 作用域内收集候选项。
  • 分别保留 SQL 类型语义和 CLR 结果语义。仅当强制转换对存储类型的影响是多余的时才移除它;对常量的强制转换可能用于确定必要的 SQL 类型。SQL 可空列本身并不能决定整形器的 nullability:对非可空标量使用 DefaultIfEmpty 时,可能需要 COALESCE 转换为其 CLR 默认值。
  • 更改查询形态时,重新映射相关状态。子查询下推或联接替换必须更新作用域内的列引用、谓词、排序、投影绑定和整形器;当多重性或 null 扩展发生变化时,应保留或重新计算标识符及其比较器。
  • 证明剪枝安全性时,不能只看最终投影。未使用的联接仍可能筛选或增加行数,因此要遵守明确的可剪枝标记以及其他子句中的引用。未引用的列仍可能决定 distinct/集合运算的成员关系,或标量子查询的结果;应保留这些约定,并确保集合运算的投影兼容。

分割查询

  • 修改 SplitQueryResultCoordinator 时,请同时检查 SplitQueryingEnumerable 和 GroupBySplitQueryingEnumerable,包括它们的同步和异步路径。流结束验证应在外层流真正耗尽时进行,而不是在分组边界或提前释放时进行。
  • 分组读取器在生成最后一个分组的过程中可能到达物理 EOF,但该分组仍须返回。应分别测试这次成功的移动和随后到达终止状态的移动,包括验证失败和重复调用终止移动;清理操作必须保留原始异常。
  • 评估内存使用时,既要考虑内部缓冲,也要考虑调用方的物化。当提供程序无法同时保持多个读取器处于活动状态时,可能需要缓冲较早的分割查询结果集;重试执行策略也可能要求缓冲。
  • 缓冲无法让不同查询命令获得一致的数据库快照。命令之间发生的并发写入可能导致结果图不一致;需要保证一致性时,可考虑快照或可序列化事务,同时权衡提供程序支持情况和事务开销。
  • 使用写入方事务,并在读取之间设置显式屏障,来验证跨命令一致性;不要使用休眠或仅用文字描述场景。断言根节点与子节点的值组合,而不只是键匹配;注明测试的隔离级别和重试策略适用范围。

验证

  • ToQueryString() 显示生成的 SQL,但不会执行查询
  • ExpressionPrinter 可在管道的任意阶段转储表达式树
  • 通过提供程序功能测试中的 AssertSql() 验证 SQL 基线,并确认生成的 SQL 与基类方法中的 LINQ 查询对应

评论

支持 Markdown