C# 在循环内实现SqlConnection的最佳方法

C# 在循环内实现SqlConnection的最佳方法,c#,sql-server,C#,Sql Server,在windows服务中,我每天处理大约24k条记录,我将行插入数据库,然后将压缩后的图像保存到目录中 一般来说,最好的方法是什么 using (SqlConnection cnn = new SqlConnection()) { foreach (var item in collection) { //do stuff SaveImage(item.filename,item.img); } } 或 如果您在每个循环上使用连接,则感谢

在windows服务中,我每天处理大约24k条记录,我将行插入数据库,然后将压缩后的图像保存到目录中

一般来说,最好的方法是什么

using (SqlConnection cnn = new SqlConnection())
{
    foreach (var item in collection)
    {
        //do stuff 

        SaveImage(item.filename,item.img);
    }
}


如果您在每个循环上使用连接,则感谢第一个解决方案,因为它不会在每个循环中重新创建


创建连接是一个耗时的过程


此外,我还建议在可能的情况下对所有查询使用单个查询,我将在循环之外构建连接。如果它是永远运行的东西,我的答案会不同,例如,如果你运行一个web服务,我建议你为每个请求打开连接(这非常不同,但我只是举个例子)。但是打开一个连接是一项资源密集型任务,在这种情况下,只打开一个连接会更容易。这真的取决于你在这里关注的是什么,正如其他一些人所说,但我认为单一的联系听起来完全可以接受。正如我看到的另一位评论者所说,如果这对您有帮助的话,您可以使用事务来完成这一切


剩下的这些并不是为了直接回答你的问题,我只是觉得考虑到你的情况,这是值得考虑的

不过,您可能需要查看SQL
MERGE
语句。如果一次可以向SQL发送多条记录,速度会快得多。当然,您仍然需要单独保存图像,但这至少可以加快SQL方面的速度。当然,您也可以使用
INSERT
语句来实现这一点,但这取决于您传递的每个新记录是否都是新的,或者是否会违反唯一键

您还可以查看,因为它有一些有用的类,用于并发和成批地执行多个操作,这可能会加快插入速度。但是请记住,单个连接有时不是处理并发请求的最佳方式。但是,如果您将数据拆分为100个集合(请记住,2100是每个
SqlCommand
的查询参数的最大数量,因此只需将其除以所需数量并减去误差范围),我可能会说,只需为每个集合创建连接即可


我知道这比你要求的要多,但是我经常处理这种情况,所以我想我会分享一些我在这一过程中学到的东西。

这里有很多因素,但在大多数情况下,我建议在循环中打开/关闭一个连接,并在连接过程中根据需要使用数据库


您将需要大量的错误处理,但如果在连接体或图像处理过程中出现故障,则可以更轻松地继续循环以获取更多记录。

如果连接中断,第一种方法将跳过整个过程

第二种方法是为每个循环创建一个新的连接,这会拖累性能

你能做的就是分批执行(比如说50次)

var batchSize=50;

对于(inti=0;iYou可能需要指定什么是最好的。效率、可读性、安全性、可维护性等。“创建连接是一个耗时的过程”事实上,如果您反复连接到同一个位置,则不是这样。ADO使用连接池,并在您关闭连接后将保持连接打开一点,以允许其他部分重新使用连接。@ScottChamberlain这不是一个在所有平台上都不保证的实现细节吗?@itsme86它是保证的。对于其他平台er
DbConnection
派生类这取决于类的实现者,但是如果设置正确,.NET可以支持它。刚刚遇到这个关于合并的问题
foreach (var item in collection)
{
    using (SqlConnection cnn = new SqlConnection())
    {
        //do stuff
    }

    SaveImage(item.filename, item.img);
}
var batchSize = 50;

for(int i = 0; i<collection.Count ; i+=batchSize)
{
     using (var cnn = new SqlConnection())
     {
      int j = 0
      foreach (var item in collection.Skip(i))
      {
        if(j++ == batchSize) continue;

         //do stuff     
         SaveImage(item.filename,item.img);     
      }
     }
}