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

.NET Core 2.2中插值字符串未转为FormattableString问题咨询

问题分析与解决方案

你忽略了C#中插值字符串的类型解析优先级规则——默认情况下,$"" 格式的插值字符串会被隐式转换为 string,而不是 FormattableString,除非你明确指定类型,或者方法没有接受 string 的重载。

为什么第二个输出不符合预期?

你的代码里有两个 FromSql 重载:一个接受 string,一个接受 FormattableString。当你调用 FromSql($"SELECT * FROM tbl WHERE fld = {filter}") 时,编译器会优先选择接受 string 的重载(因为字符串转换是C#内置的基础转换,优先级高于 FormattableString 这种用户定义的转换)。

所以第二个调用实际上执行的是 string 版本的 FromSql,直接返回了插值后的原始字符串——也就是你看到的 SELECT * FROM tbl WHERE fld = Mark'; DROP TABLE tbl; --(这里没有单引号是因为插值字符串直接替换了变量值,不像第一个调用那样手动添加了单引号)。

如何让第二个调用和第三个输出一致?

你需要明确告诉编译器把插值字符串当作 FormattableString 处理,有两种方式:

1. 显式强制转换类型

把插值字符串转换为 FormattableString 后再传入:

Console.WriteLine(FromSql((FormattableString)$"SELECT * FROM tbl WHERE fld = {filter}"));

2. 调整方法重载(可选)

如果希望所有插值字符串调用都默认走参数化逻辑,可以移除 string 版本的 FromSql,或者让 string 版本内部调用 FormattableString 版本(不过这种方式要注意原始字符串的场景)。

补充:EF Core中的实际场景

在EF Core中,官方提供的 FromSql(旧版本)或 FromSqlInterpolated(新版本)方法就是通过接受 FormattableString 来自动实现参数化查询的,从而避免SQL注入。而 FromSqlRaw 则接受 string,需要手动传入参数,这和你写的两个重载的逻辑是一致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:45:42