批量插入数据 SqlBulkCopy类

本文介绍了一种SQL Server数据库访问优化方案,利用SqlBulkCopy进行批量数据插入,并提供了模型到DataTable转换的方法及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近要优化数据库访问,数据库是SQLSERVER。

对单条数据的插入和更新,之前的做法是先查询数据库是否有记录,有就更新,没有就插入。

查了网上的资料后,别人有个好的做法是直接update,若受影响条数是0就直接插入。不知道有没有更好的。

  对与操作历史表的请求,准备做成批量插入。通过使用SqlBulkCopy来批量插入。因为采用了ORM所以批量插入的时候要转model为datatable。所以根据model写了个modelTodatatable的方法来生成datatable对象。

      

    public static DataTable ConvertToDataTable(List<T> models,string TableName)
        {
            if (models != null && models.Count > 0)
            {
                DataTable dt = string.IsNullOrEmpty(TableName) ? new DataTable(typeof(T).Name) : new DataTable(TableName);
                GetTableColumn(dt,models[0]);
                foreach (var m in models)
                {
                    DataRow dr = dt.NewRow();
                    foreach (var v in typeof(T).GetProperties())
                    {
                        if (v.PropertyType.IsValueType || v.PropertyType.Name.StartsWith("String") || v.PropertyType.IsArray)
                            dr[v.Name] = v.GetValue(m, null);
                        else
                        {
                            object value = v.GetValue(m, null);
                            foreach (var item in value.GetType().GetProperties())
                            {
                                dr[item.Name] = item.GetValue(value, null);
                            }
                        }
                    }
                    dt.Rows.Add(dr);
                }
                return dt;

            }
            else
                return null;
        }
        private static void GetTableColumn(DataTable dt, T model)
        {
            foreach (var v in typeof(T).GetProperties())
            {
                if (!v.PropertyType.IsClass || v.PropertyType.Name.StartsWith("String") || v.PropertyType.Name.Contains("[]"))
                    dt.Columns.Add(v.Name, v.PropertyType);
                else
                {
                    object value = v.GetValue(model, null);
                    foreach (var item in value.GetType().GetProperties())
                        dt.Columns.Add(item.Name, item.PropertyType);
                }
            }
        
        }
        
之前对sqlbulkcopy不了解,对应的数据库表主键是自增列,同时还有image类型,在写代码的时候遇到一些问题,现在把sqlbulkcopy的测试例子贴出来,希望对同样的新人有帮助。

    static void Main(string[] args)
        {
            SqlConnectionStringBuilder sqlstr = new SqlConnectionStringBuilder();
            sqlstr.DataSource = "WINDOWS-B7K4U6P\\SQLSERVER2012";
            sqlstr.InitialCatalog = "BULKCOPY";
            sqlstr.IntegratedSecurity = true;
            string conn = sqlstr.ConnectionString;
            DataTable dt = new DataTable("Person");
            dt.Columns.Add("Name");
            dt.Columns.Add("qq");
            dt.Columns.Add("Address");
            dt.Columns.Add("Pic",typeof(byte[]));
            object[] row = { "wxk", "ccccc","cccccc",new byte[]{0xAD,0x24}};
            object[] row1 = { "ddd", "ddddd", "ddddd", new byte[] { 0xAD, 0xAA } };
            dt.Rows.Add(row);
            dt.Rows.Add(row1);
            using (SqlBulkCopy sbc = new SqlBulkCopy(conn))
            {
                sbc.DestinationTableName = "Person";
                sbc.ColumnMappings.Add("qq", "QQ");
                sbc.ColumnMappings.Add("Pic", "picture");
                sbc.ColumnMappings.Add("Name", "Name");
                sbc.ColumnMappings.Add("Address", "Address");
 
                sbc.WriteToServer(dt);
            }
        }

在sqlbulkCopy中只要把model的属性名和数据库的字段名映射好就行,别漏掉了一个,否则就会报错。

对应的数据库表信息:

CREATE TABLE [dbo].[Person](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nchar](10) NULL,
	[Address] [nchar](10) NULL,
	[PhoneNum] [int] NULL,
	[QQ] [nchar](10) NULL,
	[picture] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值