DataReader工作不清楚

时间:2013-03-28 15:16:18

标签: c# asp.net sql sql-server ado.net

 protected void btnFetch_Click(object sender, EventArgs e)
    {

    SqlConnection con = new SqlConnection(Helper.ConStr);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = con;
    cmd.CommandText = "select * from emptable";
    con.Open();
    SqlDataReader dr = cmd.ExecuteReader();
    gv1.DataSource = dr;
    gv1.DataBind();

    dr.NextResult();

    **while (dr.Read())**//It is returning the value as false!
    {
        SqlCommand cmd1 = new SqlCommand();
        cmd1.CommandText = "select * from table1";
        Response.Write(dr[0]);
        Response.Write(dr[1]);
    }
    con.Close();
 }

我很困惑为什么,数据读取器选择一个“select语句”,读取它并将其绑定到Gridview但是当它归结为使用下一组“select语句”时,数据读取器不会做任何事。 dr.Read()变为false

请向我解释为什么会发生这种情况?

5 个答案:

答案 0 :(得分:2)

数据阅读器仅供参考。这意味着您只能读取所有行。

因此,当您绑定GridView时,它将在数据读取器中移动,直到Read()返回false(以便能够填充所有行)。

因此,当您尝试调用循环时,reader已经在记录集的末尾。

MSDN中详细解释了这一点。

更新

{@ 1}}方法用于选择下一个结果,如果您在@Petoj显示的情况下向NextResult()添加了多个SELECT语句。因此,它对您的代码没有任何影响。

答案 1 :(得分:1)

试试这个

 protected void btnFetch_Click(object sender, EventArgs e)
 {

    SqlConnection con = new SqlConnection(Helper.ConStr);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = con;
    cmd.CommandText = "select * from emptable;select * from table1";
    con.Open();
    SqlDataReader dr = cmd.ExecuteReader();
    gv1.DataSource = dr;
    gv1.DataBind();

    dr.NextResult();

    while (dr.Read())
    {
        Response.Write(dr[0]);
        Response.Write(dr[1]);
    }
    con.Close();
 }

答案 2 :(得分:1)

您不需要NextResultdr.NextResult();会将读者推向下一批:

using (var myCon = new SqlConnection(Helper.ConStr))
using (var selectCommand = new SqlCommand("select * from emptable", myCon))
{
    myCon.Open();
    using (var dr = selectCommand.ExecuteReader())
    {
        while (dr.Read()) 
        {
            // ...
        }
    }
}

因此,如果您选择两个表格,则可以使用NextResult来获取下一个表格,例如:

"select * from emptable; select * from otherTable"

通常您不需要使用此方法,因为ExecuteReader已经返回第一批。

请注意,我正在使用using-statement来确保即使出现异常,所有非托管资源也会在其末尾处理。你应该尽可能使用它。这适用于实现IDisposable的每个对象(如果在不可能的情况下尝试使用using,则会出现编译器错误。)

SqlConnection.Dispose也会关闭连接,因此您无需手动执行此操作(这适用于所有连接类型)。

MSDN

  

通常,使用IDisposable对象时,应声明和   在using语句中实例化它。 using语句调用   以正确的方式在对象上配置方法。在使用块中,对象是   只读,无法修改或重新分配。使用声明   确保在您使用时,即使发生异常,也会调用Dispose   正在调用对象上的方法。

答案 3 :(得分:0)

如果您的查询Reference中有多个select语句,则

dr.NextResult();有效 您的表中只有一个select语句

cmd.CommandText = "select * from emptable";

所以如果你必须使用多个select语句,那么在commandtext中你应该有多个select语句,如下所示

cmd.CommandText = "select * from emptable;select * from table1";

答案 4 :(得分:0)

你必须在sql server

中编写存储过程

CREATE PROCEDURE selectFromTwoTables 如 开始 开始交易

SELECT * FROM emptable

SELECT * FROM table1

IF(@@ error = 0) - 如果发生任何错误,事务将回滚。否则提交 提交交易 其他 回滚交易 END

c#中的

  SqlCommand cmd = new SqlCommand(“selectFromTwoTables”,conn);    cmd.CommandType = CommandType.StoredProcedure;