有助于减少与数据库的连接数

时间:2010-09-15 16:15:53

标签: c# .net tsql ado.net

我有一个字符串列表,它们只是发票号码。 我将通过此列表进行枚举,以从数据库中获取每张发票的详细信息。 该列表的大小很容易为700到1000。 我现在这样做的方式导致700-1000连接到数据库。 这需要很长时间才能完成 有没有更好的方法做到这一点,我只是不知道?任何指针都会很棒。

这是我的枚举的一个例子

foreach(string i in invoiceList)
{
  Invoice inv = invoiceData.GetInvoice(i);
  //do something with the invoice
}

然后这是我使用ado.net的数据访问方法的一个例子

public Invoice GetInvoice(string invoice)
{
      SqlConnection con = new SqlConnection(//connection string);
      SqlCommand cmd = new SqlCommand("dbo.getInvoices", con);
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("invoice", SqlDbType.VarChar).Value = invoice;
      SqlDataReader dr;
      Invoice inv = new Invoice();
      try{
            con.Open();
            dr = cmd.ExecuteReader
            while(dr.read())
            {
                 //assign values from the database fields
            }


      }
      catch{}
      finally{con.close();}

}

所以基本上getInvoice方法每次都会调用1000次打开一个新连接。什么是更好(更快)的方法来做到这一点。 谢谢!

5 个答案:

答案 0 :(得分:1)

您可以将连接打开和关闭代码放在循环之外。这将使您只有一个连接到数据库。但是这一个连接将暂时开放。这是权衡。一个连接打开很长时间或很多连接打开和关闭。

我也注意到你没有在try代码中关闭你的连接。也许试试这个。

public Invoice GetInvoice(string invoice)
{
      SqlConnection con = new SqlConnection(//connection string);
      SqlCommand cmd = new SqlCommand("dbo.getInvoices", con);
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("invoice", SqlDbType.VarChar).Value = invoice;
      SqlDataReader dr;
      Invoice inv = new Invoice();
      try{
            con.Open();
            dr = cmd.ExecuteReader
            while(dr.read())
            {
                 //assign values from the database fields
            }
      }
      catch{}
      finally
      {
        con.Close();
      }
}

答案 1 :(得分:1)

我在你的try-block中错过了conn.Close()

如果确实遗漏了,那可能是你的问题:你一直在建立新的联系。所以,在一个try / finally块中关闭它

但如果这是发布的代码中的拼写错误,那么我认为您的问题与Connection无关,ADO.NET使用ConnectionPooling,因此您保持“真正的”连接打开,即使您说conn.Close()。

另一个问题是对每张发票进行查询。那也很贵。但是既然你似乎使用了SP,那就不容易克服了。这里有用的是以WHERE Id IN (a, b, c, d)结尾的SELECT语句。这将允许您批量发票(通过1个查询获得5或20。

答案 2 :(得分:1)

只需将所有发票编号放在IN语句中,然后在一个连接中运行此select语句。

答案 3 :(得分:1)

这样的事情可能会有所改善。

public List<Invoice> GetInvoices(List<string> invoiceList) {
  List<Invoice> invoices = new List<Invoice>();

  Invoice inv;
  SqlDataReader dr;

  using (SqlConnection con = new SqlConnection(//connection string)) {
    using(SqlCommand cmd = new SqlCommand("dbo.getInvoices", con)) {
      cmd.CommandType = CommandType.StoredProcedure;
      SqlParameter param = cmd.Parameters.Add("invoice", SqlDbType.VarChar);

      foreach(string i in invoiceList) {
        inv = new Invoice();
        param.Value = i;
        using (dr = cmd.ExecuteReader()) {
          while(dr.read())
          {
            // assign values from the database fields
            inv.Property = dr.GetString(0);

            // Add invoice to the result list
            invoices.Add(inv);
          }
        }
      }
    }
  }

  return invoices;
}

然后你可以像这样使用这个方法......

var invoiceList = new List<string> { "123", "456", "789" };
var invoices = GetInvoices(invoiceList);
foreach(var i in invoices) {
  Console.WriteLine(i.SomeInvoiceProperty);
}

答案 4 :(得分:0)

我相信如果您一直处理700到1000个或更多发票号码,为什么不在一个查询中发送所有发票号码而不是多个单独的查询,您可能需要考虑不同的方法。例如,您可以使用列表中的sql执行此操作,如下所示。

select
 *
from
 ivoice_table
where
 invoice_table.invoice_number in (123,124,125,126,127,128 etc....)

享受!