C# 数据读取器工作不清楚

C# 数据读取器工作不清楚,c#,asp.net,sql,sql-server,ado.net,C#,Asp.net,Sql,Sql Server,Ado.net,我不明白为什么数据读取器会选择一条“select语句”,读取它并将其绑定到Gridview,但当涉及到使用下一组“select语句”时,数据读取器什么也不做dr.Read()变为false 请向我解释为什么会发生这种情况?数据读取器仅向前。这意味着您只能读取所有行一次 因此,当您绑定GridView时,它将在数据读取器中移动,直到Read()返回false(以便能够填充所有行) 因此,当您尝试调用循环时,读取器已经位于记录集的末尾 这将在中详细解释 更新: 如果将多个select语句添加到命令中

我不明白为什么数据读取器会选择一条“select语句”,读取它并将其绑定到Gridview,但当涉及到使用下一组“select语句”时,数据读取器什么也不做
dr.Read()
变为
false


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

数据读取器仅向前。这意味着您只能读取所有行一次

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

因此,当您尝试调用循环时,
读取器
已经位于记录集的末尾

这将在中详细解释

更新:


如果将多个select语句添加到
命令中,则使用
NextResult()
方法选择下一个结果。CommandText
如@Petoj所示。因此,它对代码没有任何影响。

数据读取器仅向前。这意味着您只能读取所有行一次

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

因此,当您尝试调用循环时,
读取器
已经位于记录集的末尾

这将在中详细解释

更新:

如果将多个select语句添加到
命令中,则使用
NextResult()
方法选择下一个结果。CommandText
如@Petoj所示。因此,它对您的代码没有任何影响。

试试这个

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

 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();
 }
dr.NextResult()有效。
表中只有一条select语句

 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();
 }
所以,如果您必须使用多个select语句,那么在commandtext中,您应该有多个select语句,如下所示

cmd.CommandText = "select * from emptable";
dr.NextResult()有效。
表中只有一条select语句

 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();
 }
所以,如果您必须使用多个select语句,那么在commandtext中,您应该有多个select语句,如下所示

cmd.CommandText = "select * from emptable";

您不需要
NextResult
dr.NextResult()使读取器前进到下一批:

cmd.CommandText = "select * from emptable;select * from table1";
因此,如果您选择两个表,您可以使用它们来获取下一个表,例如:

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()) 
        {
            // ...
        }
    }
}
通常不需要使用此方法,因为
ExecuteReader
已返回第一批

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

SqlConnection.Dispose
也会关闭连接,因此不需要手动操作(这适用于所有连接类型)

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


您不需要
NextResult
dr.NextResult()使读取器前进到下一批:

cmd.CommandText = "select * from emptable;select * from table1";
因此,如果您选择两个表,您可以使用它们来获取下一个表,例如:

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()) 
        {
            // ...
        }
    }
}
通常不需要使用此方法,因为
ExecuteReader
已返回第一批

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

SqlConnection.Dispose
也会关闭连接,因此不需要手动操作(这适用于所有连接类型)

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


您必须在sql server中编写存储过程

创建过程selectFromTwoTables 作为 开始 开始交易

从可清空列表中选择*

从表1中选择*

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

在c# SqlCommand cmd=newsqlcommand(“selectFromTwoTables”,conn);
cmd.CommandType=CommandType.storedProcess

您必须在sql server中编写存储过程

创建过程selectFromTwoTables 作为 开始 开始交易

从可清空列表中选择*

从表1中选择*

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

在c# SqlCommand cmd=newsqlcommand(“selectFromTwoTables”,conn);
cmd.CommandType=CommandType.storedProcess

NextResult返回什么?返回
boolean
value Btwy您应该在连接和命令上使用“using”,这样您就不必自己处理它们,如果发生异常,它们将被处理。NextResult返回什么?返回您应该使用的“使用”值