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();

            }

        }
View Code

从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; }

    }
View Code

然后测试

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");

        }
View Code

上面这段代码是直接构造的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;

        }
View Code

然后在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;

        }
View Code

 

/// <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);

        }
View Code

准备做好了,接下来看看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;

                });

            

        }
View Code

前面的构建数据表Datatable及批量插入那一段长长的Code这里一句就OK了。

当然,这里用到了委托的原理,剩下的就在以后慢慢发掘吧

 

posted on 2013-06-22 20:26  DonnyPeng  阅读(1212)  评论(0编辑  收藏  举报