My environment used is Visual Studio 2022 v17.12.4. Language is C# and connecting to SQL Server Express v16.0.1135.2. This is a Windows form using .Net Framework 4.8.1.
I am getting the error message “Invalid attempt to read when no data is present” and can't seem to find the cause. I have the following methods that I use in many places without issue. However in this one case it is causing the error. I confirmed in the method GetDataReader the reader has the row I am expecting. However in the method MaximumFieldLengthSql where it is returned to, there are no rows in the Results View and the error is thrown.
Any help pointing me in the right direction is much appreciated.
This is the result view of the reader in the GetDataReader method.

This is the result view of the reader in the MaximumFieldLengthSql method once returned.

Here are the 2 methods. The SQL statement passed to MaximumFieldLengthSql is "SELECT Max(Len(customerName)) AS L FROM Customer".
private static int MaximumFieldLengthSql(string sqlCommand)
{
int _maxLength = 0;
try
{
using (SqlDataReader reader = MyData.SQLServer.GetDataReader(sqlCommand))
{
// BUG - Reader has no rows, even though it does in SQLServer.GetDataReader
if ((reader != null) & (reader.HasRows))
{
reader.Read();
_maxLength = reader.GetInt32(0);
reader.Close();
}
}
}
catch (Exception ex)
{
string errorMessage = $"Error retrieving data from table '{Tables.CustomerTable.TableName}'”;
Logging.AddException(ex, Logging.EventNumbers.RetrievingData, errorMessage, System.Diagnostics.EventLogEntryType.Error);
}
return _maxLength;
}
// Located in the SqlServer class
internal static SqlDataReader GetDataReader(string sqlCommand)
{
SqlDataReader reader = null;
try
{
if (connection == null) { Server.InitializeConnection(); }
using (SqlCommand dbCommand = new SqlCommand(sqlCommand))
{
dbCommand.Connection = connection;
reader = dbCommand.ExecuteReader();
}
}
catch (Exception ex)
{
reader = null;
Logging.AddException(ex,
Logging.EventNumbers.RetrievingData,
"Error executing datareader",
EventLogEntryType.Error);
}
return reader;
}
Tuhin PaulPosted Jan 22, 2025, 5:13 AM
This flowchart shows the process flow from the
MaximumFieldLengthSqlmethod toGetDataReaderand the associated checks.MaximumFieldLengthSql Method:
GetDataReaderto fetch data.GetDataReader Method:
SqlCommandand executes it to get aSqlDataReader.Flow:
Tuhin PaulPosted Jan 22, 2025, 5:08 AM
Do not dispose of the
SqlCommandwithin theGetDataReadermethod. Return theSqlDataReaderwhile keeping the associatedSqlCommandandSqlConnectionalive.Tuhin PaulPosted Jan 22, 2025, 5:06 AM
Main Issues are as follows:
The
usingstatement in theGetDataReadermethod disposes of theSqlCommandafter its execution, including the associatedSqlDataReader. This disposal might cause theSqlDataReaderto lose its data or become invalid when accessed in theMaximumFieldLengthSqlmethod.The
HasRowsproperty is accessed in theMaximumFieldLengthSqlmethod. If theSqlDataReaderbecomes invalid or empty due to theusingblock inGetDataReader, it will report no rows.If
Server.InitializeConnection()does not ensure an open and valid connection, theSqlDataReadercould fail to read data despite executing a query.Pat HanksPosted Jan 22, 2025, 12:38 AM
I was given an answer by a friend that resolved the issue. All I did is make a small change in the MaximumCaliberLengthSql method as below.