I have a stored procedure that returns the correct column count, but the code below works most of the time, but INCIDENTALL throws an exception below. We recently updated .NET 4.6, and we notice this exception.
Questions:
1 Where and why does the exception occur?
2 Based on the source code below, how is it possible that the SQL client receives empty metadata from the server side?
Stored Procedure GetUser:
CREATE PROCEDURE [dbo].[GetUser]
@UserID int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @UserIDChar NVARCHAR(255);
SET @UserIDChar = convert(nvarchar(255), @UserID);
SELECT TOP 1
A.Value1 As FirstName,
A.Value2 As LastName
FROM dbo.Activity as A
WHERE A.ActivityValue = @UserIDChar
ORDER BY A.DateCreated DESC
SET NOCOUNT OFF;
END
C # web layer:
using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetUser";
cmd.Connection = cn;
cmd.Parameters.AddWithValue("@UserID", userId);
cn.Open();
using (IDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleResult))
{
if (dr.Read())
{
string firstName = (string)dr[0];
string lastName = (string)dr[1];
return firstName + " " + lastName;
}
}
}
Error:
: System.IndexOutOfRangeException
: .
: System.Collections.ListDictionaryInternal
TargetSite: Void CheckDataIsReady (Int32, Boolean, Boolean, System.String)
: System.Datap >
:
private void CheckDataIsReady(int columnIndex, bool allowPartiallyReadColumn = false, bool permitAsync = false, string methodName = null) {
if (_isClosed) {
throw ADP.DataReaderClosed(methodName ?? "CheckDataIsReady");
}
if ((!permitAsync) && (_currentTask != null)) {
throw ADP.AsyncOperationPending();
}
Debug.Assert(!_sharedState._dataReady || _metaData != null, "Data is ready, but there is no metadata?");
if ((!_sharedState._dataReady) || (_metaData == null)) {
throw SQL.InvalidRead();
}
if ((columnIndex < 0) || (columnIndex >= _metaData.Length)) {
throw ADP.IndexOutOfRange();
}
if ((IsCommandBehavior(CommandBehavior.SequentialAccess)) &&
((_sharedState._nextColumnDataToRead > columnIndex) || (_lastColumnWithDataChunkRead > columnIndex) ||
((!allowPartiallyReadColumn) && (_lastColumnWithDataChunkRead == columnIndex)) ||
((allowPartiallyReadColumn) && (HasActiveStreamOrTextReaderOnColumn(columnIndex))))) {
throw ADP.NonSequentialColumnAccess(columnIndex, Math.Max(_sharedState._nextColumnDataToRead, _lastColumnWithDataChunkRead + 1));
}
}
http://referencesource.microsoft.com/#System.Data/System/Data/SqlClient/SqlDataReader.cs,577d642dce99ed0d