[系统优化]——批量操作数据库

    写在前面的

    对于系统的优化,我们总是有说不完的经验,每一个系统的开发过程,都是系统不断的优化的过程。

        前一阵做的项目完工了。最后的维护工作也交给了我,早就听人家说做系统的维护能学到不少的东西。这次我是真有体会了。

        先交代一下背景;我们的系统有这样的一个业务需求:需要给员工分配维修任务。当然每次接到的任务会有很多,每个员工接到的任务可能有好多个,这就需要组长把任务分配到每个人。这次的系统的优化当然也是在这个陪的过程中产生了错误。

        具体的问题是:每次分配任务的时候都需要把分配信息添加到数据库,这就需要频繁的操作数据库。这样会导致操作的执行时间过长。也就是系统的相应时间。如何解决这个问题呢,这个就想到了使用数据库的批量导入功能,也就引出了我们今天的主角“SqlBulkCopy”。

         SqlBulkCopy类的主要作用:

·    单独批量复制操作,可将数据从一个数据源移动到SQL Server表中。

·    也可执行多个批量复制操作。

·    在数据库事务中可执行批量复制操作。

    代码示例:

    对于这个类的使用,找一个简单的例子说明:

#region数据库对应表
/// <summary>
/// 数据库对应表
/// </summary>
/// <returns></returns>
private static DataTable GetTable()
{
	DataTable dt = new DataTable();
	dt.Columns.Add("User_ID", typeof(string));
	dt.Columns.Add("User_Name", typeof(string));
	dt.Columns.Add("User_Birth", typeof(DateTime));
	dt.Columns.Add("User_Sex", typeof(int));
	return dt;
}
#endregion
 
/// <summary>
/// 批量插入数据
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public void AddModels(List<UserEntity> users)
{ 
	//实例化一个和数据库一样的dataTable        
	DataTable dt_users = GetTable();
	//把实体类的信息插入到dataTable中
	foreach (UserEntity model in users)
	{
		DataRow dr_user = dt_users.NewRow();
		 //生成随机码作为主键             
		dr_user ["User_ID"] = Guid.NewGuid().Tostring();
		dr_user ["User_Name "] = model.UserName;
		dr_user ["User_Birth "] = model.UserBirth;
		dr_user ["UserSex"] = model.Sex;
		dt_users.Rows.Add(dr_user);
	}
	if (dt_users != null && dt_user.Rows.Count > 0)
	{
		using (SqlConnection conn= new SqlConnection(ConfigurationManager.ConnectionStrings["DBConn"].ConnectionString))
		{
			conn.Open();
			using (SqlTransaction trans = conn.BeginTransaction())
			{
				try
				{
					using (SqlBulkCopy bulk= new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, trans))
					{
						//设置每一批次中的行数。在每一批次结束时,将该批次中的行发送到服务器。
						bulk.BatchSize = 1000000;
						//设置服务器上目标表的名称
						bulk.DestinationTableName = "db_User";
						//已重载。 将所有行从数据源复制到 SqlBulkCopy 对象的 DestinationTableName 属性指定的目标表中。
						bulk.WriteToServer(dt_users);
						trans.Commit();
						IsRead = true;
					}
				}
				catch
				{
					IsRead = false;
					trans.Rollback();
				}
			}
		}
	}
}

分析:

上面的例子完成了数据库的批量的导入。基本步骤如下:

  1. 建立与数据库表结构相同的dataTable数据表。其中需要注意的是:如果表中有空数据且空数据的列位于表的最后一列或几列时,在dataTable中可以不用建立对应列。
  2. 循环赋值,把每一条需要添加到数据库中的数据对应的保存到datarow中并且添加到dataTable中,值得注意的是如果对应于数据库表中中间的某列或某几列的数据为Null则可不对dataTable中对应的列赋值。
  3. 开启一个事务,把整个执行过程放在事务里执行。
  4. 初始化SqlBulkCopy 构造函数 (SqlConnection, SqlBulkCopyOptions, SqlTransaction)。其中比较重要的一个参数就是SqlBulkCopyOptions枚举中的值的组合,该枚举确定将哪些数据源行复制到目标表中。其中如果想在插入时激发插入触发器,应将其设置为SqlBulkCopyOptions.FireTriggers.
  1. 开始操作数据库。(具体见注释。)

    通过上面说明我想大家对SqlBulkCopy这个类有了一定的了解了。当然我想到的这个类还有一个很重要的用途就是可以向数据库中批量导入数据。导入excel表格中的数据。具体的操作下篇介绍。



你可能感兴趣的:(优化,事务,经验)