在项目中,我们经常会遇见把某个数据库中的某个表全部记录移动到另一个数据库中的某个表中,或则在某个数据库中两个表中进行数据数据的复制。
ADO.NET提供一个类 SqlBulkCopy类,避免了往某个表或者另一个数据库某个表进行循环插入(在数据量很大、性能要求严格循环访问数据库不实用).
创建一个数据库DataBaseBulkCopy,并在这个数据库创建2个表,分别为MD_Area和Md_AreaInfo
sql 脚本
1 CREATE DATABASE DataBaseBulkCopy
2 USE DataBaseBulkCopy
3 GO
4 CREATE TABLE MD_Area(
5 ID INT,
6 AreaId INT,
7 QuotationType INT,
8 GoodsTypeId INT,
9 ParentId INT
10 )
11 USE DataBaseBulkCopy
12 GO
13 CREATE TABLE MD_AreaInfo(
14 ID INT,
15 CnName VARCHAR(50),
16 EnName VARCHAR(50),
17 AreaCode VARCHAR(50),
18 Discription NVARCHAR(500),
19 ParentId INT,
20 IsDelete BIT,
21 ShowOrder INT,
22 LastModifyBy INT,
23 LastModifyDate DATETIME
24 )
在webConfig配置两个数据库链接:
View Code
<appSettings>
<add key="ConnStr" value="Data Source=.;Initial Catalog=xb_quotation_dev;Persist Security Info=True;User ID=sa;Password=123456"/>
<add key="ConnStr_1" value="Data Source=.;Initial Catalog=DataBaseBulkCopy;Persist Security Info=True;User ID=sa;Password=123456"/>
</appSettings>
ADO.NET实现:
ADO.NET
1 protected void btnSave_Click(object sender, EventArgs e)
2 {
3 string sql = "SELECT * FROM MD_Area;SELECT * FROM MD_AreaInfo;";
4 DataSet ds = SelectCommand(sql);
5 string connectionString = ConfigurationManager.AppSettings["ConnStr_1"].ToString();
6 SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder(connectionString);
7 sb.MultipleActiveResultSets = true;
8 using (SqlConnection conn = new SqlConnection(sb.ConnectionString))
9 {
10 conn.Open();
11 using (SqlTransaction tran = conn.BeginTransaction())
12 {
13 int rowsAffects;
14 using (SqlCommand cmd = conn.CreateCommand())
15 {
16 cmd.CommandText = "DELETE FROM MD_Area;DELETE FROM MD_AreaInfo;";
17 cmd.Transaction = tran;
18 rowsAffects = cmd.ExecuteNonQuery();
19 }
20 SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.CheckConstraints, tran);
21 copy.ColumnMappings.Clear();
22 foreach (DataColumn dc in ds.Tables[0].Columns)
23 {
24 copy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);
25 }
26 copy.DestinationTableName = "MD_Area";
27 try
28 {
29 copy.WriteToServer(ds.Tables[0]);
30 }
31 catch (Exception ex)
32 {
33 tran.Rollback();
34 throw;
35 }
36 copy.ColumnMappings.Clear();
37 foreach (DataColumn dc in ds.Tables[1].Columns)
38 {
39 copy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);
40 }
41 copy.DestinationTableName = "MD_AreaInfo";
42 try
43 {
44 copy.WriteToServer(ds.Tables[1]);
45 }
46 catch (Exception ex)
47 {
48 tran.Rollback();
49 throw;
50 }
51 tran.Commit();
52 }
53 }
54 }
55 #region 获得相应查询语句的数据表
56 /// <summary>
57 /// 获得相应查询语句的数据表
58 /// </summary>
59 /// <param name="strSelect">传入sql查询语句</param>
60 /// <returns></returns>
61 public DataSet SelectCommand(string strSelect)
62 {
63 string connectionString = ConfigurationManager.AppSettings["ConnStr"].ToString();
64 using (SqlConnection con = new SqlConnection(connectionString))
65 {
66 using (SqlCommand cmd = con.CreateCommand())
67 {
68 cmd.CommandText = strSelect;
69 SqlDataAdapter da = new SqlDataAdapter(cmd);
70 DataSet ds = new DataSet();
71 da.Fill(ds);
72 return ds;
73 }
74 }
75 }
76 #endregion
可以看到SqlBulkCopy通过让DataSet,DataTable,DataReader中大量的数据通过数据流直接进行装载,然后可以将这些记录添加到指定的数据表中。
一些常用属性:
DestinationTableName:指定的目标表。
ColumnMappings:返回SqlBulkColumnMapping项的集合,列映射定义数据源中的列和目标列之间的关系。如果数据源与目标表具有相同的列数,且数据源每个源序号列匹配目标表中的对应列,则可以不用显示写出ColumnMappings结合,如果列数不同,或者不对应,则需要写出;
View Code
1 protected void btnSave_Click(object sender, EventArgs e)
2 {
3 string sql = "SELECT * FROM MD_Area;SELECT * FROM MD_AreaInfo;";
4 DataSet ds = SelectCommand(sql);
5 string connectionString = ConfigurationManager.AppSettings["ConnStr_1"].ToString();
6 SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder(connectionString);
7 sb.MultipleActiveResultSets = true;
8 using (SqlConnection conn = new SqlConnection(sb.ConnectionString))
9 {
10 conn.Open();
11 using (SqlTransaction tran = conn.BeginTransaction())
12 {
13 int rowsAffects;
14 using (SqlCommand cmd = conn.CreateCommand())
15 {
16 cmd.CommandText = "DELETE FROM MD_Area;DELETE FROM MD_AreaInfo;DELETE FROM MD_Area_Dev;";
17 cmd.Transaction = tran;
18 rowsAffects = cmd.ExecuteNonQuery();
19 }
20 SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.CheckConstraints, tran);
21 copy.ColumnMappings.Clear();
22 foreach (DataColumn dc in ds.Tables[0].Columns)
23 {
24 copy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);
25 }
26 copy.DestinationTableName = "MD_Area";
27 try
28 {
29 copy.WriteToServer(ds.Tables[0]);
30 }
31 catch (Exception ex)
32 {
33 tran.Rollback();
34 throw;
35 }
36 copy.ColumnMappings.Clear();
37 foreach (DataColumn dc in ds.Tables[1].Columns)
38 {
39 copy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName);
40 }
41 copy.DestinationTableName = "MD_AreaInfo";
42 try
43 {
44 copy.WriteToServer(ds.Tables[1]);
45 }
46 catch (Exception ex)
47 {
48 tran.Rollback();
49 throw;
50 }
51 copy.ColumnMappings.Clear();
52 copy.ColumnMappings.Add("ID", "ID");
53 copy.ColumnMappings.Add("AreaID", "CityID");
54 copy.DestinationTableName = "MD_Area_Dev";
55 try
56 {
57 copy.WriteToServer(ds.Tables[0]);
58 }
59 catch (Exception ex)
60 {
61 tran.Rollback();
62 throw;
63 }
64 tran.Commit();
65 }
66 }
67 }