代码之家  ›  专栏  ›  技术社区  ›  Vinko Vrsalovic

有没有一种方法可以让SqlConnection在关联的DataReader打开时进行写入?

  •  2
  • Vinko Vrsalovic  · 技术社区  · 16 年前

    或者,建议同时读写的方式是什么?打开两个连接是唯一的方法吗?这是一个普通的WindowsFormsC#(.NET3.5)应用程序

    using (SqlConnection conn = new SqlConnection(connStr)) {
        SqlCommand cmdRead = new SqlCommand("select stools from foo", conn);
        SqlDataReader rdr = cmdRead.ExecuteReader();
        SqlCommand cmdWrite = new SqlCommand("insert into bar values (@beer)", conn);
        SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int);
        cmdWrite.Parameters.Add(beer);
        while(rdr.Read()) {
            int stools = rdr.GetInt32(0);
            cmdWrite.Parameters["@beer"].value = stools;
            //Next line fails for an open data reader associated to the "command"
            cmdWrite.ExecuteNonQuery(); 
        }
        rdr.Close()
    }
    

    using (SqlConnection connR = new SqlConnection(connStr)) {
        using (SqlConnection connW = new SqlConnection(connStr)) {
            SqlCommand cmdRead = new SqlCommand("select stools from foo", connR);
            SqlDataReader rdr = cmdRead.ExecuteReader();
            SqlCommand cmdWrite = new 
                             SqlCommand("insert into bar values (@beer)", connW);
            SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int);
            cmdWrite.Parameters.Add(beer);
            while(rdr.Read()) {
                int stools = rdr.GetInt32(0);
                cmdWrite.Parameters["@beer"].value = stools;
                cmdWrite.ExecuteNonQuery(); 
            }
            rdr.Close()
        }
    }
    

    在这个简单的例子中,读取所有的凳子,将它们存储在一个列表中,关闭读卡器,然后将它们写入即可(只要数据库中没有太多凳子),但在更复杂的情况下,它开始变得笨重和内存不足,因此这也是不可取的。

    4 回复  |  直到 16 年前
        1
  •  3
  •   RickNZ    16 年前

    使用SQL 2005及更高版本,您可以使用多个活动结果集(MARS):

    http://msdn.microsoft.com/en-us/library/ms345109%28SQL.90%29.aspx

    http://msdn.microsoft.com/en-us/library/ms131686.aspx

    要使其工作,您需要在连接字符串中启用它。

        2
  •  2
  •   George Stocker NotMe    16 年前

    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmdRead = new SqlCommand("select stools from foo", conn))
    {
        conn.Open();  
        using (SqlDataReader rdr = cmdRead.ExecuteReader())
        {
            while(rdr.Read()) 
            {
                int stools = rdr.GetInt32(0);
            }
        }
    }
    

    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmdWrite = new SqlCommand("insert into bar values (@beer)", conn))
    {
        conn.Open();
        SqlParameter beer = new SqlParameter("@beer", SqlDbType.Int);
        cmdWrite.Parameters.Add(beer);
        cmdWrite.Parameters["@beer"].value = stools;
        cmdWrite.ExecuteNonQuery(); 
    }
    

    然后在不同的线程上调用它们。这使得方法更清晰、更具体。

        3
  •  1
  •   Pedro    16 年前

    当DataReader打开时,您不能进行写入,在这种情况下需要创建第二个连接,而且这不是设计问题。

        4
  •  1
  •   Murph    16 年前

    一个明显的问题是,你为什么要在代码中这样做?

    您正在从一个表中选择要写入另一个表-这让我尖叫着插入查询。

    毫无疑问,现实世界的例子更复杂,在这种情况下,您需要两个连接,因为DataReader的工作方式是保持连接打开,直到您完成为止,这或多或少就是这样。

    推荐文章