【问题标题】:SqlDataReader Reader.Read() shows Enumeration yielded no resultsSqlDataReader Reader.Read() 显示枚举未产生结果
【发布时间】:2017-11-09 21:09:12
【问题描述】:

我正在尝试从给定的表中生成随机 ID。我可以看到在调试中生成的随机数,但是当我到达 reader.Read() 行时,它显示 Enumeration 没有产生任何结果。

我无法完全理解我所缺少的。

  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();
            }

        }

        }

    }

【问题讨论】:

  • 为什么Id 会大于maxValueRAND() 的乘积?
  • 另外,reader[int] 是从零开始的。所以你的数据(如果你有的话)将在reader[0]。顺便说一句,如果您到达 Console.WriteLine 行,这意味着至少有 1 行结果。最后,调用reader.Close() 是不必要的(如果返回多于1 行,实际上会破坏它)。 using 负责这一点。也许你想使用break;
  • 你将不得不钳制 rand 返回的值而不是乘以它

标签: c# sqlcommand


【解决方案1】:

由于您基本上是在搜索现有记录的随机 ID,我相信这可能涵盖您正在尝试做的事情:

Random record from a database table (T-SQL)

从指针 ORDER BY NEWID() 中选择前 1 个 ID

改用 SqlCommand.ExecuteScalar 方法

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

你的例子的问题:

问题 1:您不能使用 SELECT @max = MAX(Id) FROM 指针计算 @max 吗?无需在参数中传递它。还是我错过了重点?这是故意的限制吗?

问题 2:不应该是 reader[0] 还是 reader["Id"]?我相信列是从零开始的,您选择的列的名称是“Id”。

问题 3:注意不要通过调试器以某种方式枚举阅读器,因为您实际上会在那里消费(一些?)结果(我猜您是通过您的评论这样做的 "//在这里我可以_看到_生成的随机值"),当遇到 reader.Read() 时,将不会有任何结果,因为 reader 已经被枚举并且不会“倒带”。 p>

https://msdn.microsoft.com/en-us/library/aa326283%28v=vs.71%29.aspx

DataReader cursor rewind

问题4:既然已经保证了关闭和废弃,为什么还要手动关闭阅读器?您也已经知道这将是返回(最多)TOP 1 的一条记录。

【讨论】:

  • 谢谢。使用 Use SqlCommand.ExecuteScalar Method 代替帮助我解决了这个问题。
  • 太棒了!不客气。出于学术原因,您应该能够通过您的示例得到您想要的东西,所以问题仍然存在于那里真正出了什么问题。不过,ExecuteScalar 更适合这种情况,因为它是专门为此设计的,无需自己处理数据读取器。
【解决方案2】:

如果您在调试器中检查 sqlDataReader 的结果,结果就会消失,并且不会被 Read() 事件找到

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 2015-08-24
    • 2020-02-25
    相关资源
    最近更新 更多