简体   繁体   中英

SqlParameter: Argument is not used in format string from Resharper

After install Resharper on my VS 2017, I have this warning on SqlParameter argument.

Argument is not used in format string

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

The solution that resharper proposes to me is to remove redundant argument.

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

Is there something wrong with my code?

The reason for this warning is FromSql overload you are using is decorated with special Resharper attribute, StringFormatMethodAttribute . This attribute

Indicates that the marked method builds string by the format pattern and (optional) arguments. The parameter, which contains the format string, should be given in constructor. The format string should be in System.String.Format(System.IFormatProvider,System.String,System.Object[])-like form.

So, FromSql signature looks like this:

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

Where sql is format pattern, and parameters is arguments to format string, as Resharper thinks because of the above attribute.

Then Resharper sees that you don't have any positional parameters in your format string (positional parameter is like {0} , {1} etc - what you would use for String.Format ), and sees that you pass an argument. It correctly (because of attribute) thinks that this parameter is useless, because format string doesn't contain any placeholder for it. It expects you would use it like this (like with String.Format ):

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

And this is also valid usage (EF Core will convert that 1 into parameter and substitute it, so it's not SQL injection).

But as you know, this same method supports another way to pass parameters, one that you are using. However, Resharper has no way of knowing that. Method is decorated with StringFormatMethod attribute and Resharper, again correctly, assumes that it's always used like this.

So this problem is not on Resharper side, but on EF Core side, because mixing different way of passing parameters, and then decorating method with attribute which forces Resharper to think only one is valid is not a very good idea. It would have been better to not mark it at all then.

To workaround you can use "string-format" way of passing parameters as shown above, but that's of course not always desirable. You can prevent Resharper from analyzing this expression by moving query to separate variable or doing something like:

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

Or disable warning with comment:

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

But all that is ugly. Real soltuion is open an issue at EF Core github tracker and ask them to fix it.

The problem here is that the string literal is being translated as a RawSqlString which you can see in the method signature if you mouse over FromSql .

A workaround to get rid of the warning could be to use a string variable for your query.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM