.NET6+EF Core6升级后LINQ插值字符串报错相关问题咨询
报错原因复现
你遇到的错误是升级到.NET 6 + C# 10之后的典型兼容性问题,最简复现代码如下:
const string suffix = "a"; var temp = new [] {"0a","1a","2a","3b"}.AsQueryable().Where((element,count) => element == $"{count}{suffix}");
问题1:报错的根本技术原因
C# 10(随.NET 6发布)引入了字符串插值处理器(InterpolatedStringHandler)特性优化插值性能:
- .NET 6之前的C#版本中,字符串插值会被编译器直接转换为
string.Format()或者string.Concat()的普通方法调用,这类调用是表达式树原生支持的,所以之前不会报错。 - .NET 6+中,当插值表达式的目标类型没有被显式声明为
string时,编译器会优先尝试将插值表达式转换为对应的插值处理器实例,而表达式树至今不支持这类插值处理器的转换操作,因此在LINQ to SQL/EF Core这类需要把Lambda转换为表达式树的场景下就会抛出你看到的错误。
并不是表达式树禁止使用字符串插值,只是新的插值编译逻辑生成的语法节点不在表达式树的支持范围内。你提前把插值结果存到局部变量的方案是官方推荐的修复方式,相当于显式告诉编译器插值结果是string类型,不会生成插值处理器相关逻辑。
问题2:IDE标红但项目可正常构建的原因
这个现象和你项目的诊断规则配置有关:
- 你在IDE里看到的红色波浪线,是IDE内置的Roslyn分析器(或者EF Core专用分析器)的实时检测结果,这类实时分析默认会启用所有已安装的分析规则,所以能第一时间检测到表达式树不支持插值处理器的错误。
- 项目构建时的诊断规则是独立配置的:
- 你开的
<TreatWarningsAsErrors>只会把编译器默认纳入构建流程的警告提升为错误,而表达式树不支持插值处理器的诊断IDCS8993在部分版本的SDK中默认没有被纳入构建的警告列表,或者默认严重级别为「建议」而非「警告」,不会被<TreatWarningsAsErrors>捕获。 - 如果你没有显式在项目里配置分析级别为最新、或者没有安装EF Core的官方分析器NuGet包,构建时不会触发这个诊断的校验,所以不会报错。
- 你开的
如果要让构建阶段也拦截这类错误,可以在项目的.editorconfig里显式配置dotnet_diagnostic.CS8993.severity = error即可。
内容的提问来源于stack exchange,提问作者mu88
相关产品推荐
相关产品推荐

