[英]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.