问题
I am Trying to generate random Ids from a given table. I can see the random number generated in debug but when I reach to reader.Read() line it shows Enumeration yielded no results.
I couldn't quite get what I am missing.
private static void GetRandomId(int maxValue)
{
string connectionString =
"Data Source=local;Initial Catalog=Test;user id=Test;password=Test123;";
string queryString = @"SELECT TOP 1 Id from Pointer WHERE Id > (RAND() * @max);";
using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("@max", maxValue);
connection.Open();
using (var reader = command.ExecuteReader()) <-- // Here I can see the randon value generated
{
while (reader.Read())
{
//Here reader shows : Enumeration yielded no results
Console.WriteLine("Value", reader[1]);
reader.Close();
}
}
}
}
回答1:
Since you are basically searching for a random Id of an existing record, I believe this may cover what you are trying to do:
Random record from a database table (T-SQL)
SELECT TOP 1 Id FROM Pointer ORDER BY NEWID()
Use SqlCommand.ExecuteScalar Method instead
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar%28v=vs.110%29.aspx
var dbRandomId = command.ExecuteScalar();
var randomId = Convert.IsDbNull(dbRandomId) ? (int?)null : (int)dbRandomId;
// you now also know if an id was returned with randomId.HasValue
https://msdn.microsoft.com/en-us/library/system.convert.isdbnull%28v=vs.110%29.aspx
Issues with your example:
Issue 1: Couldn't you have @max be computed with a SELECT @max = MAX(Id) FROM Pointer? No need to pass it in a parameter. Or am I missing the point? Is that a deliberate limit?
Issue 2: Shouldn't it be reader[0] or reader["Id"]? I believe columns are zero based and your selected column's name is "Id".
Issue 3: Be careful not to enumerate somehow the reader via the Debugger because you'll actually consume (some of?) the results right there (I'm guessing you are doing this by your comment "// Here I can _see_ the random value generated") and by the time the reader.Read() is encountered there will be no results left since the reader has already been enumerated and it won't "rewind".
https://msdn.microsoft.com/en-us/library/aa326283%28v=vs.71%29.aspx
DataReader cursor rewind
Issue 4: Why do you close the reader manually when you've already ensured the closing & disposal with using? You also already know it's going to be one record returned (the most) with the TOP 1.
回答2:
If you check the results of the sqlDataReader in the debugger, the results are then gone, and wont be found by the Read() event
来源:https://stackoverflow.com/questions/30041745/sqldatareader-reader-read-shows-enumeration-yielded-no-results