C# SqlBulkCopy批量插入数据
SqlBulkCopy用其他源的数据有效批量加载 SQL Server 表
关于SqlBulkCopy的更多信息,请点击http://msdn.microsoft.com/zh-cn/library/vstudio/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx
这里记录一个简单的示例
首先先在MSSql中建一张测试的用户表,包括UserId(主键,自增),Name(varchar),Age(int),Sex(varchar),这里code就不贴出来了
然后看看C#代码里怎么用的吧
还是定义一个SQLHelper帮助类,里面的内容如下:
//这里只是测试用,实际上这个链接字符串应该从配置文件里面读取 public static readonly string connStr = "server=.;database=UserDB;uid=sa;pwd=******"; /// <summary> /// 创建SqlConnection对象 /// </summary> /// <returns></returns> public static SqlConnection GetConn() { return new SqlConnection(connStr); } /// <summary> /// SQLServer批量插入数据功能 /// 这是SQLServer特有的功能,故不再上层抽象类中编写 /// </summary> /// <param name="dt">数据表</param> /// <param name="tableName">表名称</param> public static void BulkInsert(SqlConnection conn, DataTable dt, string tableName) { if (string.IsNullOrEmpty(tableName)) { throw new ArgumentNullException("请指定需要插入的数据表"); } var count = dt.Rows.Count; if (count == 0) { return; } if (conn.State == ConnectionState.Closed) { conn.Open(); } //SqlBulkCopy用其他源的数据有效批量加载 SQL Server 表 //更多点击http://msdn.microsoft.com/zh-cn/library/vstudio/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx using (SqlBulkCopy copy = new SqlBulkCopy(conn)) { copy.BatchSize = dt.Rows.Count;//每一批次中的行数。在每一批次结束时,将该批次中的行发送到服务器。 copy.DestinationTableName = tableName;//指定目标表 copy.WriteToServer(dt);//将dt中的所有行复制到SqlBulkCopy对象的DestinationTableName指定的目标表中 conn.Close(); } }
从BulkInsert的方法参数可以看出需要SqlConnection连接对象,数据源DataTable和目标表名称。
既然要数据源,那就简单构造一个数据源实体
public class UserInfo { public int UserId { get; set; } public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } }
然后测试
static void Main(string[] args) { //构造的数据源 List<UserInfo> list = new List<UserInfo>() { new UserInfo(){ Name="zhangsan",Age=21,Sex="男"}, new UserInfo(){ Name="lisi",Age=23,Sex="女"}, new UserInfo(){ Name="wangwu",Age=22,Sex="男"} }; //列名称 var clist = new[] {"UserId","Name", "Age", "Sex" }; //构建DataTable DataTable dt = new DataTable(); foreach (var item in clist) { dt.Columns.Add(item,item.GetType()); } for (int i = 0; i < list.Count; i++) { DataRow newRow = dt.NewRow(); newRow["Name"] = list[i].Name; newRow["Age"] = list[i].Age; newRow["Sex"] = list[i].Sex; dt.Rows.Add(newRow); } //批量插入 SqlHelper.BulkInsert(SqlHelper.GetConn(), dt, "UserInfo"); }
上面这段代码是直接构造的DataTable,下面看看进一步封装的Code。
先加一个DataRowWaper类,用来构建行里的列
private DataRow row = null; public DataRowWaper(DataRow row) { this.row = row; } public DataRow Row { get { return this.row; } } public object this[DataColumn column] { get { return this.row[column]; } set { this.row[column] = value; } } public object this[int columnIndex] { get { return this.row[columnIndex]; } set { this.row[columnIndex] = value; } } public object this[string columnName] { get { return this.row[columnName]; } set { this.row[columnName] = value; } } public void SetValue(string key, object value) { this.row[key] = value; }
然后在SQLHelper类里加两个方法
/// <summary> /// 创建数据表 /// </summary> /// <param name="columns"></param> public static DataTable CreateTable(IList<string> columns) { var dt = new DataTable(); foreach (var c in columns) { dt.Columns.Add(c); } return dt; }
/// <summary> /// 批量插入数据 /// </summary> /// <param name="tableName">数据表</param> /// <param name="columns">字段</param> /// <param name="dataList">数据列表</param> /// <param name="action">具体操作</param> public static void CreateInner<T>(SqlConnection conn, string tableName, IList<string> columns, IList<T> dataList, Action<DataRowWaper, T, int> action) { if (string.IsNullOrEmpty(tableName)) { throw new ArgumentNullException("需要指定操作的数据表"); } if (columns == null || columns.Count == 0) { throw new ArgumentNullException("数据表列不能为空"); } var dt = CreateTable(columns); if (action != null) { for (var i = 0; i < dataList.Count; i++) { var wapper = new DataRowWaper(dt.NewRow()); action(wapper, dataList[i], i); dt.Rows.Add(wapper.Row); } } BulkInsert(conn, dt, tableName); }
准备做好了,接下来看看Main方法
static void Main(string[] args) { //构造的数据源 List<UserInfo> list = new List<UserInfo>() { new UserInfo(){ Name="zhangsan",Age=21,Sex="男"}, new UserInfo(){ Name="lisi",Age=23,Sex="女"}, new UserInfo(){ Name="wangwu",Age=22,Sex="男"} }; //列名称 var clist = new[] {"UserId","Name", "Age", "Sex" }; SqlHelper.CreateInner<UserInfo>(SqlHelper.GetConn(), "UserInfo", clist, list, (curow, userInfo, i) => { curow["UserId"] = userInfo.UserId; curow["Name"] = userInfo.Name; curow["Age"] = userInfo.Age; curow["Sex"] = userInfo.Sex; }); }
前面的构建数据表Datatable及批量插入那一段长长的Code这里一句就OK了。
当然,这里用到了委托的原理,剩下的就在以后慢慢发掘吧