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