使用多结果集读取数据减少服务器往返,提高性能

先来谈一下什么是多结果集?以及为什么需要它?

假设我们的一个窗体上有多个控件,需要绑定多个数据源。那么传统情况下,我们可以用不同的命令去读取不同的数据,然后分别绑定。这样做本来无可厚非,但如果从性能上考虑的话,就有改进的必要了。

因为每个单独的命令执行都是需要发生一次服务器的往返的,所以如果能够把数据一次性读取到,统一发给用户程序,再在客户端做单独的绑定,这样的设计可以减少服务器往返次数,提高性能。

以下是一些代码和比较

使用DataReader执行单结果集查询:每次返回一个结果集。(这是传统的方式)

using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
{
    SqlCommand cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT CustomerID FROM Customers";
    conn.Open();
    SqlDataReader reader1 = cmd.ExecuteReader();
    DataTable tb1 = new DataTable();
    tb1.Load(reader1);

    listBox1.DataSource = tb1;
    listBox1.DisplayMember = "CustomerID";
    reader1.Close();

    SqlCommand cmd2 = conn.CreateCommand();
    cmd2.CommandText = "SELECT OrderID,OrderDate FROM Orders";
    SqlDataReader reader2 = cmd2.ExecuteReader();
    DataTable tb2 = new DataTable();
    tb2.Load(reader2);
    dataGridView2.DataSource = tb2;
    reader2.Close();
    conn.Close();
}

很显然,这样的话,就会发生两次的服务器往返。(两次批处理的过程)

image

使用DataReader做多结果集查询:一次性读取两个表格的数据

using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString + ";MultipleActiveResultSets=true"))
{
    SqlCommand cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT CustomerID FROM Customers;SELECT OrderID FROM Orders";
    conn.Open();
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        listBox1.Items.Add(reader[0].ToString());
    }

    while (reader.NextResult())
    {
        while (reader.Read())
        {
            listBox2.Items.Add(reader[0].ToString());
        }
    }

    reader.Close();
    conn.Close();
}

image

需要特别注意的是,因为DataReader是一个只向前,只读的游标集。所以如果它的结果集有超过一个,需要通过NextResult方法进行移动。同时,还需要启用MARS:多活动结果集 的支持。

 

如果换成是DataSet的方式,就无需这么麻烦,因为DataSet天生就是支持多个表格,在用DataAdatper的Fill方法填充数据的时候,它会自动地建立多个表格在DataSet里面。

using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
{
    SqlCommand cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT CustomerID FROM Customers;SELECT OrderID FROM Orders";
    conn.Open();

    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    DataSet ds = new DataSet();
    adapter.Fill(ds);

    this.listBox1.DataSource = ds.Tables[0];
    listBox1.DisplayMember = "CustomerID";
    this.dataGridView2.DataSource = ds.Tables[1];
    conn.Close();
}

image

posted @ 2008-07-29 16:02  陈希章  阅读(474)  评论(0编辑  收藏  举报