有没有办法让一个SqlConnection在关联的DataReader打开时写入?

时间:2009-12-18 10:59:07

标签: c# .net sql-server

或者推荐的同时读写方式是什么?打开两个连接是唯一的方法吗?这是在一个简单的Windows Forms C#(.NET 3.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()
}

这个,OTOH,可以工作,但看起来很难看(除了打开额外的连接)

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 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:2)

为什么不使用两种方法:一种用于读取,一种用于写入,每种方法都使用从连接池中提取的自己的连接。

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

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

答案 2 :(得分:1)

在DataReader打开时无法写入,在这种情况下需要创建第二个连接,恕我直言,这不是设计问题。

答案 3 :(得分:1)

显而易见的问题是你为什么要在代码中执行此操作?

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

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