避免在循环中调用数据库操作:提升C#程序性能的有效方法

开发 前端
在C#程序开发中,通过避免在循环中调用数据库操作,可以显著提升程序性能,减少数据库负担,提升代码的可维护性。

其实最佳实践是用像SqlSugar这样的ORM类来搞。在开发C#应用程序时,特别是在处理大量数据时,不可避免地需要与数据库进行交互。然而,如果在循环中频繁进行数据库操作,会导致性能问题、增加数据库负担,甚至可能导致瓶颈。本文将探讨如何避免在循环中进行数据库操作,并提供详细的例子来说明这些方法。

为什么要避免在循环中调用数据库操作?

在循环中进行数据库操作会带来以下几个问题:

  • 性能问题:每一次数据库操作都会涉及网络通信、IO操作和数据库处理时间,频繁调用会大幅降低程序的性能。
  • 增加数据库负担:频繁的数据库访问会占用数据库连接,增加数据库服务器的负荷,影响整体系统的性能。
  • 降低代码可维护性:分散的数据库操作代码难以维护和优化。

方法一:批量操作

示例1:批量插入数据

不建议的方法:

foreach (var item in list)
{
    using (var connection = new SqlConnection(connectionString))
    {
        var command = new SqlCommand("INSERT INTO MyTable (Col1) VALUES (@value)", connection);
        command.Parameters.AddWithValue("@value", item);
        connection.Open();
        command.ExecuteNonQuery();
    }
}

建议的方法:

using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (var transaction = connection.BeginTransaction())
    {
        var command = new SqlCommand();
        command.Connection = connection;
        command.Transaction = transaction;
        foreach (var item in list)
        {
            command.CommandText += "INSERT INTO MyTable (Col1) VALUES (@value_" + item.Id + ");";
            command.Parameters.AddWithValue("@value_" + item.Id, item.Value);
        }
        command.ExecuteNonQuery();
        transaction.Commit();
    }
}

通过批量操作,可以减少数据库交互次数,极大地提升性能。

方法二:缓存数据到内存中

示例2:缓存数据一次性加载

不建议的方法:

foreach (var item in list)
{
    using (var connection = new SqlConnection(connectionString))
    {
        var command = new SqlCommand("SELECT * FROM MyTable WHERE Id = @id", connection);
        command.Parameters.AddWithValue("@id", item.Id);
        connection.Open();
        var reader = command.ExecuteReader();
        while (reader.Read())
        {
            // 处理数据
        }
    }
}

建议的方法:

var data = new List<DataItem>();
using (var connection = new SqlConnection(connectionString))
{
    var command = new SqlCommand("SELECT * FROM MyTable WHERE SomeCondition = @condition", connection);
    command.Parameters.AddWithValue("@condition", condition);
    connection.Open();
    var reader = command.ExecuteReader();
    while (reader.Read())
    {
        var dataItem = new DataItem
        {
            Id = reader.GetInt32(0),
            Name = reader.GetString(1)
        };
        data.Add(dataItem);
    }
}
// 在内存中处理数据
foreach (var item in data)
{
    item.Processed = true;
}


using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    foreach (var item in data)
    {
        var command = new SqlCommand("UPDATE MyTable SET Processed = @processed WHERE Id = @id", connection);
        command.Parameters.AddWithValue("@processed", item.Processed);
        command.Parameters.AddWithValue("@id", item.Id);
        command.ExecuteNonQuery();
    }
}

示例3:预加载数据

将数据加载到内存中进行处理而不是在循环中每次访问数据库,可以显著提高性能。

方法三:使用存储过程

示例4:使用存储过程进行批量更新

SQL Server 中存储过程示例:

CREATE PROCEDURE BulkUpdateMyTable
   @DataTable MyTableType READONLY
AS
BEGIN
    UPDATE t
    SET t.Processed = d.Processed
    FROM MyTable t
    INNER JOIN @DataTable d ON t.Id = d.Id
END

C#代码调用存储过程:

DataTable dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(int));
dataTable.Columns.Add("Processed", typeof(bool));


foreach (var item in data)
{
    dataTable.Rows.Add(item.Id, item.Processed);
}


using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (var command = new SqlCommand("BulkUpdateMyTable", connection))
    {
        command.CommandType = CommandType.StoredProcedure;
        var parameter = command.Parameters.AddWithValue("@DataTable", dataTable);
        parameter.SqlDbType = SqlDbType.Structured;
        command.ExecuteNonQuery();
    }
}

通过使用存储过程,可以一次性将所有需要处理的数据传递给存储过程,由存储过程完成批量处理。

结论

在C#程序开发中,通过避免在循环中调用数据库操作,可以显著提升程序性能,减少数据库负担,提升代码的可维护性。本文通过三个主要的方法(批量操作、缓存数据和使用存储过程)提供了详细的解决方案和示例代码,希望能够帮助开发者更好地优化数据库交互操作。

在实际开发中,应根据具体的业务场景选择合适的方法进行优化,从而提升系统的整体性能和稳定性。

责任编辑:武晓燕 来源: 技术老小子
相关推荐

2024-05-16 11:04:06

C#异步编程编程

2024-09-20 18:02:42

C#数据库SQLite

2024-05-17 13:01:31

C#编程开发

2024-04-18 09:56:16

2019-02-01 09:50:00

提升Python程序性能

2009-08-24 18:09:13

C#调用Oracle数

2009-08-17 17:42:57

C#数据库操作类

2009-08-12 14:23:01

C#连接MySql数据

2011-09-20 10:41:45

Web

2022-10-08 13:13:14

Python程序性能

2018-07-06 16:26:11

编程语言Python程序性能

2009-08-10 18:05:19

C#数据库查询

2009-08-19 16:30:55

C#操作Access数

2012-05-19 22:24:34

MVVM

2011-03-30 10:41:11

C++数据库

2011-05-17 16:20:46

C++

2021-08-18 09:37:51

数据库移动应用程序

2009-08-18 11:23:11

2011-04-08 09:52:44

C++C#DLL

2009-08-19 16:40:26

C#操作Access数
点赞
收藏

51CTO技术栈公众号