繁体   English   中英

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

[英]help with reducing the number of connections to the database

我有一个字符串列表,它们只是发票编号。 我将通过此列表进行枚举,以从数据库中获取每张发票的详细信息。 该列表的大小很容易为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次打开一个新连接。 什么是更好(更快)的方法来做到这一点。 谢谢!

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

我也注意到你没有在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();
      }
}

我在你的try-block中缺少conn.Close()

如果它确实缺失,那可能是你的问题:你一直在建立新的连接。 所以,在try / finally块中关闭它

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

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

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

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

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

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

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

请享用!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM