首页 > 解决方案 > SqlParameter:Resharper 的格式字符串中未使用参数

问题描述

在我的 VS 2017 上安装 Resharper 后,我在 SqlParameter 参数上收到此警告。

参数未在格式字符串中使用

var children = context.FluxoHierarchy
    .FromSql("get_children_fluxo_closure @node_id", new SqlParameter("@node_id", queueItem.ProximoNode)).ToList();

resharper 向我提出的解决方案是删除多余的参数。

var children = context.FluxoHierarchy
    .FromSql("get_children_fluxo_closure @node_id").ToList();

我的代码有问题吗?

标签: c#resharperentity-framework-core

解决方案


此警告的原因是FromSql您使用的重载被特殊的 Resharper 属性StringFormatMethodAttribute修饰。这个属性

指示标记的方法通过格式模式和(可选)参数构建字符串。包含格式字符串的参数应在构造函数中给出。格式字符串应采用类似 System.String.Format(System.IFormatProvider,System.String,System.Object[]) 的形式。

所以,FromSql签名看起来像这样:

[StringFormatMethod("sql")]
public static IQueryable<TEntity> FromSql<TEntity>(this IQueryable<TEntity> source, RawSqlString sql, params object[] parameters)

格式模式在哪里sql,并且parameters是格式字符串的参数,正如 Resharper 认为的那样,因为上述属性。

然后 Resharper 发现您的格式字符串中没有任何位置参数(位置参数类似于{0}{1}等等 - 您将用于String.Format),并看到您传递了一个参数。它正确地(因为属性)认为这个参数是无用的,因为格式字符串不包含任何占位符。它希望你会像这样使用它(比如 with String.Format):

FromSql("get_children_fluxo_closure {0}", 1).ToList();

这也是有效的用法(EF Core 会将其转换1为参数并替换它,因此它不是 SQL 注入)。

但如您所知,同样的方法支持另一种传递参数的方式,即您正在使用的方式。然而,Resharper 无法知道这一点。方法用StringFormatMethod属性修饰,Resharper 再次正确地假设它总是这样使用。

所以这个问题不在 Resharper 方面,而是在 EF Core 方面,因为混合不同的参数传递方式,然后用属性装饰方法,迫使 Resharper 认为只有一个有效,这不是一个好主意。那时最好不要标记它。

要解决方法,您可以使用“字符串格式”方式传递参数,如上所示,但这当然并不总是可取的。您可以通过将查询移动到单独的变量或执行以下操作来阻止 Resharper 分析此表达式:

FromSql(new RawSqlString("get_children_fluxo_closure @node_id"), new SqlParameter("@node_id", 1)).ToList();

或禁用带有注释的警告:

// ReSharper disable once FormatStringProblem
FromSql("get_children_fluxo_closure @node_id", new SqlParameter("@node_id", 1)).ToList();

但这一切都是丑陋的。真正的解决方案是在 EF Core github tracker 上打开一个问题并要求他们修复它。


推荐阅读