SqlParameter:参数没有在Resharper的格式化字符串中使用

3
在我的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();

我的代码有问题吗?


context.Blogs.FromSql("SELECT * FROM [dbo].SearchBlogs", new SqlParameter("@searchTerm", userSuppliedSearchTerm)) context.Blogs.FromSql("SELECT * FROM [dbo].SearchBlogs", new SqlParameter("@searchTerm", userSuppliedSearchTerm)) - Vivek Nuna
2个回答

9
这个警告的原因是你正在使用带有特殊Resharper属性StringFormatMethodAttribute修饰的FromSql重载。该属性表示标记方法通过格式模板和(可选)参数构建字符串。包含格式字符串的参数应在构造函数中给出,格式字符串应采用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),并且发现你传递了一个参数。由于属性的正确性,它认为该参数是无用的,因为格式字符串中不包含任何占位符。它期望你像这样使用它(就像使用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 跟踪器上开一个问题,并要求他们修复它。


1
已提交问题[#12002](https://github.com/aspnet/EntityFrameworkCore/issues/12002)。 - bricelam
2
而且解决方案是“不会修复”,因为“决定对于常见情况,属性的值大于在使用@语法的情况下的假阴性”。 - Ivan Stoev
1
@IvanStoev 这真的很令人惊讶,甚至可以说是令人担忧。 - Evk

2
这里的问题在于字符串字面量被翻译为一个 RawSqlString,你可以将鼠标悬停在 FromSql 上查看方法签名。
消除警告的一种解决办法是使用一个字符串变量来作为查询。
string query = "get_children_fluxo_closure @node_id";
var children = context.FluxoHierarchy
    .FromSql(query, new SqlParameter("@node_id", queueItem.ProximoNode))
    .ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接