使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用 IDataReader 实例读取数据

  1. 使用Datatable作为数据源的方式:

下面的代码使用到了ColumnMappings,因为目标表和数据源Datatable的结构不一致,需要这么一个映射来指定对应关系

  1. public string SaveJHCData(LzShopBasicData[] datas)
  2. {
  3. var result = new AResult();
  4. SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["**"].ConnectionString);
  5. con.Open();
  6. foreach (var item in datas)
  7. {
  8.  
  9. Logger.Info("数据更新处理,店铺名称:" + item.ShopName + "数据日期" + item.SellDate);
  10. try
  11. {
  12. using (TransactionScope scope = new TransactionScope())
  13. {
  14.  
  15. DataTable JHCOrderItemsdt = SaveJHCOrderItemsData(item);
  16. SqlBulkCopy JHCOrderItemscopy = new SqlBulkCopy(con);
  17. JHCOrderItemscopy.ColumnMappings.Add("orderId", "orderId");
  18. JHCOrderItemscopy.ColumnMappings.Add("auctionId", "auctionId");
  19. JHCOrderItemscopy.ColumnMappings.Add("itemTitle", "itemTitle");
  20. JHCOrderItemscopy.ColumnMappings.Add("tradeAmt", "tradeAmt");
  21. JHCOrderItemscopy.ColumnMappings.Add("alipayNum", "alipayNum");
  22. JHCOrderItemscopy.ColumnMappings.Add("tradeTime", "tradeTime");
  23. JHCOrderItemscopy.ColumnMappings.Add("uv", "uv");
  24. JHCOrderItemscopy.ColumnMappings.Add("srcId", "srcId");
  25. JHCOrderItemscopy.ColumnMappings.Add("srcName", "srcName");
  26. JHCOrderItemscopy.ColumnMappings.Add("DataType", "DataType");
  27. JHCOrderItemscopy.ColumnMappings.Add("DataDate", "DataDate");
  28. JHCOrderItemscopy.ColumnMappings.Add("OrderSourceID", "OrderSourceID");
  29. JHCOrderItemscopy.ColumnMappings.Add("ShopName", "ShopName");
  30. JHCOrderItemscopy.DestinationTableName = "JHCOrderItems";
  31. JHCOrderItemscopy.WriteToServer(JHCOrderItemsdt);
  32. result.Updatedata += ;
  33. result.UpdatedataText += item.SellDate + ",";
  34. scope.Complete();
  35. Logger.Info(item.SellDate + "事务提交");
  36. }
  37. }
  38. catch (Exception ex)
  39. {
  40. Logger.Error(ex.ToString());
  41. continue;
  42. }
  43. }
  44. con.Close();
  45. return result.ToSerializeObject();
  46. }

2.使用IDataReader作为数据源的方式,这种方式个人认为用的很少,首先目标表和来源表两个数据库连接你都需要拿到,如果两个都可以拿到,一般直接操作sql就可以解决:

这里是直接拷贝的MSDN的代码,

用到的AdventureWorks数据库可以直接在网上下载到,

  1. using System.Data.SqlClient;
  2.  
  3. class Program
  4. {
  5. static void Main()
  6. {
  7. string connectionString = GetConnectionString();
  8. // Open a sourceConnection to the AdventureWorks database.
  9. using (SqlConnection sourceConnection =
  10. new SqlConnection(connectionString))
  11. {
  12. sourceConnection.Open();
  13.  
  14. // Perform an initial count on the destination table.
  15. SqlCommand commandRowCount = new SqlCommand(
  16. "SELECT COUNT(*) FROM " +
  17. "dbo.BulkCopyDemoMatchingColumns;",
  18. sourceConnection);
  19. long countStart = System.Convert.ToInt32(
  20. commandRowCount.ExecuteScalar());
  21. Console.WriteLine("Starting row count = {0}", countStart);
  22.  
  23. // Get data from the source table as a SqlDataReader.
  24. SqlCommand commandSourceData = new SqlCommand(
  25. "SELECT ProductID, Name, " +
  26. "ProductNumber " +
  27. "FROM Production.Product;", sourceConnection);
  28. SqlDataReader reader =
  29. commandSourceData.ExecuteReader();
  30.  
  31. // Open the destination connection. In the real world you would
  32. // not use SqlBulkCopy to move data from one table to the other
  33. // in the same database. This is for demonstration purposes only.
  34. using (SqlConnection destinationConnection =
  35. new SqlConnection(connectionString))
  36. {
  37. destinationConnection.Open();
  38.  
  39. // Set up the bulk copy object.
  40. // Note that the column positions in the source
  41. // data reader match the column positions in
  42. // the destination table so there is no need to
  43. // map columns.
  44. using (SqlBulkCopy bulkCopy =
  45. new SqlBulkCopy(destinationConnection))
  46. {
  47. bulkCopy.DestinationTableName =
  48. "dbo.BulkCopyDemoMatchingColumns";
  49.  
  50. try
  51. {
  52. // Write from the source to the destination.
  53. bulkCopy.WriteToServer(reader);
  54. }
  55. catch (Exception ex)
  56. {
  57. Console.WriteLine(ex.Message);
  58. }
  59. finally
  60. {
  61. // Close the SqlDataReader. The SqlBulkCopy
  62. // object is automatically closed at the end
  63. // of the using block.
  64. reader.Close();
  65. }
  66. }
  67.  
  68. // Perform a final count on the destination
  69. // table to see how many rows were added.
  70. long countEnd = System.Convert.ToInt32(
  71. commandRowCount.ExecuteScalar());
  72. Console.WriteLine("Ending row count = {0}", countEnd);
  73. Console.WriteLine("{0} rows were added.", countEnd - countStart);
  74. Console.WriteLine("Press Enter to finish.");
  75. Console.ReadLine();
  76. }
  77. }
  78. }
  79.  
  80. private static string GetConnectionString()
  81. // To avoid storing the sourceConnection string in your code,
  82. // you can retrieve it from a configuration file.
  83. {
  84. return "Data Source=(local); " +
  85. " Integrated Security=true;" +
  86. "Initial Catalog=AdventureWorks;";
  87. }
  88. }

实战:借助类型反射动态构建Datatable数据源,通过SqlBulkCopy批量保存入库

1.获取一张空的Datatable

  1. var dt = bisdal.From<TopBrand>(TopBrand._.ID == -, OrderByClip.Default).ToDataTable();

2.填充DataTable,这里是通过遍历外部的集合,把属性属性逐一赋值填充到目标Datatable

  1. foreach (var item in brandselldataitems)
  2. {
  3. try
  4. {
  5.  
  6. TopBrand topbrand = new TopBrand
  7. {
  8. BrandIndex = item.mk,
  9. BrandName = item.c58,
  10. Date = date,
  11. WinnerAmt = item.c60,
  12. WinnerPeople = item.c62,
  13. WinnerProNum = item.c61,
  14. HotTaobaoCategoryID = cid
  15. };
  16. CreateDtByItem<TopBrand>(topbrand, dt);
  17. }
  18. catch (Exception ex)
  19. {
  20. Logger.Error(ex.ToString());
  21. continue;
  22. }
  23. }

这里借助反射,遍历实体属性集合,动态构建DataTableRow对象

  1. private void CreateDtByItem<T>(T item, DataTable dt)
  2. {
  3. System.Reflection.PropertyInfo[] properties = item.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
  4. var newrow = dt.NewRow();
  5. foreach (System.Reflection.PropertyInfo pitem in properties)
  6. {
  7.  
  8. string name = pitem.Name;
  9. if (name == "children")
  10. {
  11. continue;
  12. }
  13. object value = pitem.GetValue(item, null);
  14. newrow[name] = value == null ? DBNull.Value : value;
  15. }
  16. dt.Rows.Add(newrow);
  17. }

3.保存入库,

  1. BulkWriteToServer(con, "TopBrand", dt);

这里因为目标表和数据源的Datatable数据结构一致,所以省去了ColumnMappings列映射的操作,可以直接WriteToServer保存

  1. private void BulkWriteToServer(SqlConnection con, string destinationtablename, DataTable sourcedt)
  2. {
  3. try
  4. {
  5. if (con.State == ConnectionState.Closed)
  6. {
  7. con.Open();
  8. }
  9. SqlBulkCopy topbranddtcopy = new SqlBulkCopy(con);
  10. topbranddtcopy.DestinationTableName = destinationtablename;
  11. topbranddtcopy.WriteToServer(sourcedt);
  12. con.Close();
  13. }
  14. catch (Exception ex)
  15. {
  16. Logger.Error("批量新增数据:" + destinationtablename + "," + ex.ToString());
  17. }
  18. }

完整调用代码:

  1. private void CreateTopBrandData(int date, int cid, List<BrandSellDataItem> brandselldataitems)
  2. {
  3. try
  4. {
  5. var dt = bisdal.From<TopBrand>(TopBrand._.ID == -, OrderByClip.Default).ToDataTable();
  6. foreach (var item in brandselldataitems)
  7. {
  8. try
  9. {
  10.  
  11. TopBrand topbrand = new TopBrand
  12. {
  13. BrandIndex = item.mk,
  14. BrandName = item.c58,
  15. Date = date,
  16. WinnerAmt = item.c60,
  17. WinnerPeople = item.c62,
  18. WinnerProNum = item.c61,
  19. HotTaobaoCategoryID = cid
  20. };
  21. CreateDtByItem<TopBrand>(topbrand, dt);
  22. }
  23. catch (Exception ex)
  24. {
  25. Logger.Error(ex.ToString());
  26. continue;
  27. }
  28. }
  29. BulkWriteToServer(con, "TopBrand", dt);
  30. }
  31. catch (Exception ex)
  32. {
  33. throw new Exception("CreateTopBrandData:" + ex.ToString());
  34. }
  35. }

SqlBulkCopy 批量复制数据到数据表的更多相关文章

  1. SqlBulkCopy(批量复制)使用方法 && SqlDataAdapter Update

    SqlBulkCopy提供了一种将数据复制到Sql Server数据库表中高性能的方法.SqlBulkCopy 包含一个方法 WriteToServer,它用来从数据的源复制数据到数据的目的地. Wr ...

  2. (转)SqlBulkCopy批量复制数据

    在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还是进行不同数据源之间的迁移,都不是很方便.而 在.Net2.0中,SQLClient命名空间下增加了几个新类帮助我们 ...

  3. 使用SqlBulkCopy批量插入多条数据进入表中

    由于工作中项目需求结算一次生成一批相同批次号的数据插入一个表中,然后再通过另一页面展示出来,所以需要用到一次性插入一批数据,所以就采用了SqlBulkCopy插入一批数据 1 public stati ...

  4. SqlBulkCopy(批量复制)使用方法

    SqlBulkCopy提供了一种将数据复制到Sql Server数据库表中高性能的方法.SqlBulkCopy 包含一个方法 WriteToServer,它用来从数据的源复制数据到数据的目的地. Wr ...

  5. SqlBulkCopy 批量复制数据到数据库

    1.简介 1.MSDN 核心方法:SqlBulkCopy.WriteToServer 将所有行从数据源复制到 SqlBulkCopy 对象的 DestinationTableName 属性指定的目标表 ...

  6. 【转】批量复制操作(SqlBulkCopy)的出错处理:事务提交、回滚

    原文地址:http://blog.csdn.net/westsource/article/details/6658109 默认情况下,批量复制操作作为独立的操作执行. 批量复制操作以非事务性方式发生, ...

  7. SqlBulkCopy批量添加

    /// <summary> /// 添加数据 /// 注:DataTable列名必须和数据库列名一致 /// </summary> /// <returns>< ...

  8. 用python库openpyxl操作excel,从源excel表中提取信息复制到目标excel表中

    现代生活中,我们很难不与excel表打交道,excel表有着易学易用的优点,只是当表中数据量很大,我们又需要从其他表册中复制粘贴一些数据(比如身份证号)的时候,我们会越来越倦怠,毕竟我们不是机器,没法 ...

  9. 用SqlBulkCopy批量插入数据到SqlServer数据库表中

    首先创建一个数据库连接类:SQLHelper using System; using System.Collections.Generic; using System.Linq; using Syst ...

随机推荐

  1. (转)SVN分支/合并原理及最佳实践

    先说说什么是branch.按照Subversion的说法,一个branch是某个development line(通常是主线也即trunk)的一个拷贝,见下图: branch存在的意义在于,在不干扰t ...

  2. CentOS与ubuntu添加eclipse桌面快捷方式的方法整理

    CentOS环境下用右键添加启动器的方式安装(ubuntu早期版本也是这样的) [1]用rmp包安装jdk, 在/usr/local目录下安装:命令 #rpm -ivh   jdk.rpm 然后#vi ...

  3. mono中显示debug信息(filename/lineno)

    一直发现 mono 的 traceback 没有 fliename.lineno,很奇怪.研究了下,原来编译和运行时要加参数的. dmcs -debug /r:xunit.dll /t:library ...

  4. yii2 funson86\yii2-setting

    Yii2 Setting for other application, especially for Yii2 Adminlte Installation The preferred way to i ...

  5. zabbix特性

    在知道zabbix是什么之后,我们最关心的是zabbix有什么特性,了解特性之后,我们才能决定是否会使用zabbix,以及zabbix是否适合我们. 概述 Zabbix是一个高度集成的网络监控套件,通 ...

  6. Java并发编程核心方法与框架-phaser的使用

    arriveAndAwaitAdvance()方法 arriveAndAwaitAdvance()作用是当前线程已经到达屏障,在此等待一段时间,等条件满足后继续向下一个屏障执行. public cla ...

  7. JS刷新页面总和!多种JS刷新页面代码!

    1)<meta http-equiv="refresh"content="10;url=跳转的页面">10表示间隔10秒刷新一次2)<scri ...

  8. php从零开始

    吐槽:今天开始撸PHP了,从此前端少了个小白,PHP多了个小白... 本白从3年前陆陆续续开始一会儿撸会儿PHP一会儿撸前端.前端撸的比较多,PHP撸的比较少,当然本白撸php大多都是被逼的!! 然后 ...

  9. Android中实现圆角矩形及半透明效果。

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在做Android开发时,我们为了美观,有时候需要使用圆角矩形,或半透明之类的效果,在网页设计中很容易实现.但在Android开发中 ...

  10. 机器码call和jmp地址的计算

    call和jmp都是跳转指令,但是call的同时会把pc地址压入堆栈,并且这两种方式都有远和近跳转.下面的分析不全,因为没有在网上找到足够的资料,个人创造这个情景还是有些困难. 1.例子中的call的 ...