程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> SqlBulkCopy 批量復制數據到數據表,sqlbulkcopy數據

SqlBulkCopy 批量復制數據到數據表,sqlbulkcopy數據

編輯:C#入門知識

SqlBulkCopy 批量復制數據到數據表,sqlbulkcopy數據


使用 SqlBulkCopy 類只能向 SQL Server 表寫入數據。但是,數據源不限於 SQL Server;可以使用任何數據源,只要數據可加載到 DataTable 實例或可使用 IDataReader 實例讀取數據

下面的代碼使用到了ColumnMappings,因為目標表和數據源Datatable的結構不一致,需要這麼一個映射來指定對應關系

  public string SaveJHCData(LzShopBasicData[] datas)
        {
            var result = new AResult();
            SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["**"].ConnectionString);
            con.Open();
            foreach (var item in datas)
            {

                Logger.Info("數據更新處理,店鋪名稱:" + item.ShopName + "數據日期" + item.SellDate);
                try
                {
                    using (TransactionScope scope = new TransactionScope())
                    {

                        DataTable JHCOrderItemsdt = SaveJHCOrderItemsData(item);
                        SqlBulkCopy JHCOrderItemscopy = new SqlBulkCopy(con);
                        JHCOrderItemscopy.ColumnMappings.Add("orderId", "orderId");
                        JHCOrderItemscopy.ColumnMappings.Add("auctionId", "auctionId");
                        JHCOrderItemscopy.ColumnMappings.Add("itemTitle", "itemTitle");
                        JHCOrderItemscopy.ColumnMappings.Add("tradeAmt", "tradeAmt");
                        JHCOrderItemscopy.ColumnMappings.Add("alipayNum", "alipayNum");
                        JHCOrderItemscopy.ColumnMappings.Add("tradeTime", "tradeTime");
                        JHCOrderItemscopy.ColumnMappings.Add("uv", "uv");
                        JHCOrderItemscopy.ColumnMappings.Add("srcId", "srcId");
                        JHCOrderItemscopy.ColumnMappings.Add("srcName", "srcName");
                        JHCOrderItemscopy.ColumnMappings.Add("DataType", "DataType");
                        JHCOrderItemscopy.ColumnMappings.Add("DataDate", "DataDate");
                        JHCOrderItemscopy.ColumnMappings.Add("OrderSourceID", "OrderSourceID");
                        JHCOrderItemscopy.ColumnMappings.Add("ShopName", "ShopName");
                        JHCOrderItemscopy.DestinationTableName = "JHCOrderItems";
                        JHCOrderItemscopy.WriteToServer(JHCOrderItemsdt);
                        result.Updatedata += 1;
                        result.UpdatedataText += item.SellDate + ",";
                        scope.Complete();
                        Logger.Info(item.SellDate + "事務提交");
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.ToString());
                    continue;
                }
            }
            con.Close();
            return result.ToSerializeObject();
        }

 2.使用IDataReader作為數據源的方式,這種方式個人認為用的很少,首先目標表和來源表兩個數據庫連接你都需要拿到,如果兩個都可以拿到,一般直接操作sql就可以解決:

這裡是直接拷貝的MSDN的代碼,

用到的AdventureWorks 數據庫可以直接在網上下載到,

using System.Data.SqlClient; class Program { static void Main() { string connectionString = GetConnectionString(); // Open a sourceConnection to the AdventureWorks database. using (SqlConnection sourceConnection = new SqlConnection(connectionString)) { sourceConnection.Open(); // Perform an initial count on the destination table. SqlCommand commandRowCount = new SqlCommand( "SELECT COUNT(*) FROM " + "dbo.BulkCopyDemoMatchingColumns;", sourceConnection); long countStart = System.Convert.ToInt32( commandRowCount.ExecuteScalar()); Console.WriteLine("Starting row count = {0}", countStart); // Get data from the source table as a SqlDataReader. SqlCommand commandSourceData = new SqlCommand( "SELECT ProductID, Name, " + "ProductNumber " + "FROM Production.Product;", sourceConnection); SqlDataReader reader = commandSourceData.ExecuteReader(); // Open the destination connection. In the real world you would // not use SqlBulkCopy to move data from one table to the other // in the same database. This is for demonstration purposes only. using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { destinationConnection.Open(); // Set up the bulk copy object. // Note that the column positions in the source // data reader match the column positions in // the destination table so there is no need to // map columns. using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection)) { bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns"; try { // Write from the source to the destination. bulkCopy.WriteToServer(reader); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { // Close the SqlDataReader. The SqlBulkCopy // object is automatically closed at the end // of the using block. reader.Close(); } } // Perform a final count on the destination // table to see how many rows were added. long countEnd = System.Convert.ToInt32( commandRowCount.ExecuteScalar()); Console.WriteLine("Ending row count = {0}", countEnd); Console.WriteLine("{0} rows were added.", countEnd - countStart); Console.WriteLine("Press Enter to finish."); Console.ReadLine(); } } } private static string GetConnectionString() // To avoid storing the sourceConnection string in your code, // you can retrieve it from a configuration file. { return "Data Source=(local); " + " Integrated Security=true;" + "Initial Catalog=AdventureWorks;"; } } View Code

 

實戰:借助類型反射動態構建Datatable數據源,通過SqlBulkCopy批量保存入庫

1.獲取一張空的Datatable

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

2.填充DataTable,這裡是通過遍歷外部的集合,把屬性屬性逐一賦值填充到目標Datatable

         foreach (var item in brandselldataitems)
                    {
                        try
                        {

                            TopBrand topbrand = new TopBrand
                            {
                                BrandIndex = item.mk,
                                BrandName = item.c58,
                                Date = date,
                                WinnerAmt = item.c60,
                                WinnerPeople = item.c62,
                                WinnerProNum = item.c61,
                                HotTaobaoCategoryID = cid
                            };
                            CreateDtByItem<TopBrand>(topbrand, dt);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex.ToString());
                            continue;
                        }
                    }

 這裡借助反射,遍歷實體屬性集合,動態構建DataTableRow對象

       private void CreateDtByItem<T>(T item, DataTable dt)
        {
            System.Reflection.PropertyInfo[] properties = item.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            var newrow = dt.NewRow();
            foreach (System.Reflection.PropertyInfo pitem in properties)
            {

                string name = pitem.Name;
                if (name == "children")
                {
                    continue;
                }
                object value = pitem.GetValue(item, null);
                newrow[name] = value == null ? DBNull.Value : value;
            }
            dt.Rows.Add(newrow);
        }

3.保存入庫,

     BulkWriteToServer(con, "TopBrand", dt);

 這裡因為目標表和數據源的Datatable數據結構一致,所以省去了ColumnMappings列映射的操作,可以直接WriteToServer保存

     private void BulkWriteToServer(SqlConnection con, string destinationtablename, DataTable sourcedt)
        {
            try
            {
                if (con.State == ConnectionState.Closed)
                {
                    con.Open();
                }
                SqlBulkCopy topbranddtcopy = new SqlBulkCopy(con);
                topbranddtcopy.DestinationTableName = destinationtablename;
                topbranddtcopy.WriteToServer(sourcedt);
                con.Close();
            }
            catch (Exception ex)
            {
                Logger.Error("批量新增數據:" + destinationtablename + "," + ex.ToString());
            }
        }

 

完整調用代碼:

 private void CreateTopBrandData(int date, int cid, List<BrandSellDataItem> brandselldataitems)
        {
            try
            {
                var dt = bisdal.From<TopBrand>(TopBrand._.ID == -1, OrderByClip.Default).ToDataTable();
                foreach (var item in brandselldataitems)
                {
                    try
                    {

                        TopBrand topbrand = new TopBrand
                        {
                            BrandIndex = item.mk,
                            BrandName = item.c58,
                            Date = date,
                            WinnerAmt = item.c60,
                            WinnerPeople = item.c62,
                            WinnerProNum = item.c61,
                            HotTaobaoCategoryID = cid
                        };
                        CreateDtByItem<TopBrand>(topbrand, dt);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.ToString());
                        continue;
                    }
                }
                BulkWriteToServer(con, "TopBrand", dt);
            }
            catch (Exception ex)
            {
                throw new Exception("CreateTopBrandData:" + ex.ToString());
            }
        }

 


用SqlBulkCopy批量插入數據 遇到的錯誤

留聯系看,晚上在線。
 

導入excel把數據存在datatable中,用sqlbulkcopy把datable批量導入到數據庫的表中

winform還是net?如果是winfrom參考下面的代碼吧!

public void ExcelIntoDatagridView()
{
//打開一個文件選擇框
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Excel文件";
ofd.FileName = "";
ofd.Filter = "Excel文件(*.xls)|";
try
{
if (ofd.ShowDialog() == DialogResult.OK)
{
string tableName = "";
//if (arratlist != null)
//{
// arratlist.Clear();
//}
string Path = ofd.FileName;
string strConn = "Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + Path + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
System.Data.DataTable schemaTable = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
tableName = schemaTable.Rows[0][2].ToString().Trim();
//for (int i = 0; i < schemaTable.Rows.Count; i++)
//{
// arratlist.Add(schemaTable.Rows[i][2].ToString().TrimStart('/'').Trim('/'', '$'));//
......余下全文>>
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved