-
What language is this for? C#
-
Which rule? S6966: Awaitable method should be used
-
Why do you believe it’s a false-positive/false-negative? Microsoft’s suggested best practices for
SqlDataReaderare that the non-async methods should be used unless theSqlDataReaderwas created using aCommandBehaviorvalue ofSequentialAccess.When the
SequentialAccessflag is not used, then the entire row will be retrieved from the server and made available in local memory by theReadAsync()call.IsDBNullAsyncandGetFieldValueAsyncwill never await, so using them just adds overhead. The async methods should not be used in this case (the default forSqlDataReader).This definitely applies to both the methods on both
System.Data.SqlClient.SqlDataReaderandMicrosoft.Data.SqlClient.SqlDataReader. It should apply to anyDbDataReadersubclass:
If sequential mode isn’t specified, all column values should become available in memory each time ReadAsync completes, and calling the synchronous version of the method shouldn’t block the calling thread.
- Are you using
- SonarQube Community Build v26.3.0.120487
- SonarQube for Visual Studio 9.9.0.16418, in connected mode
- How can we reproduce the problem?
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
namespace SonarQubeRepros
{
internal sealed class S6966FalsePositiveRepoSqlClientAsync
{
public static async Task<string> GetValueAsync()
{
using (var connection = new SqlConnection())
{
using (var cmd = new SqlCommand("SELECT * FROM sys.tables", connection))
{
await connection.OpenAsync();
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var ordinal = reader.GetOrdinal("name");
if (!reader.IsDBNull(ordinal))
{
return reader.GetFieldValue<string>(ordinal);
}
}
}
}
}
return null;
}
}
}
Both the IsDBNull and GetFieldValue calls are detected by S6966.