1. 程式人生 > >【物流系統】——C#Oracle批量匯入(二)OracleBulkCopy

【物流系統】——C#Oracle批量匯入(二)OracleBulkCopy

前提

    上一版的匯入十分麻煩,2W的資料量和宕機了似得。經過不斷的探索,終於搞出了優化後的一版,優化之後用時不超過5秒。下面就是demo了,哈哈。

    因為我在解析完xml之後把所有的資料都放到list中了,但是使用OracleBulkCopy,實現就是表和表之間的複製,就是把資料放到DataTable中,然後直接複製到資料庫對應的表中。

OracleBulkCopy使用

所以利用此方法就是實現,需要先把list轉成DataTable。

        public DataTable ListToDataTable<T>(List<T> entitys)
        {
            //檢查實體集合不能為空
            if (entitys == null || entitys.Count < 1)
            {
                throw new Exception("需轉換的集合為空");
            }
            //取出第一個實體的所有Propertie
            Type entityType = entitys[0].GetType();
            PropertyInfo[] entityProperties = entityType.GetProperties();

            //生成DataTable的structure
            //生產程式碼中,應將生成的DataTable結構Cache起來,此處略
            DataTable dt = new DataTable();
            for (int i = 0; i < entityProperties.Length; i++)
            {
                //dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
                dt.Columns.Add(entityProperties[i].Name);
            }
            //將所有entity新增到DataTable中
            foreach (object entity in entitys)
            {
                //檢查所有的的實體都為同一型別
                if (entity.GetType() != entityType)
                {
                    throw new Exception("要轉換的集合元素型別不一致");
                }
                object[] entityValues = new object[entityProperties.Length];
                for (int i = 0; i < entityProperties.Length; i++)
                {
                    entityValues[i] = entityProperties[i].GetValue(entity, null);
                }
                dt.Rows.Add(entityValues);
            }
            return dt;
        }
下面是快速插入的方法
        public void BulkToDB(DataTable dt, string targetTable)
        {
            string connOrcleString = "Data Source=;User Id=;Password=;";
            string err = "大批量插入時產生錯誤";
            Oracle.DataAccess.Client.OracleConnection conn = new Oracle.DataAccess.Client.OracleConnection(connOrcleString);
            if (conn.State != ConnectionState.Open)
            { conn.Open(); }
            Oracle.DataAccess.Client.OracleBulkCopy bulkCopy = new Oracle.DataAccess.Client.OracleBulkCopy(conn, Oracle.DataAccess.Client.OracleBulkCopyOptions.Default);
            bulkCopy.BatchSize = 100000;
            bulkCopy.BulkCopyTimeout = 260;
            //targetTable目標表名
            bulkCopy.DestinationTableName = targetTable;

            try
            {
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
                // conn.Open();  
                if (dt != null && dt.Rows.Count != 0)
                {
                    bulkCopy.WriteToServer(dt);

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                conn.Close();
                if (bulkCopy != null)
                    bulkCopy.Close();
            }

        }
呼叫關係
            DataTable dt = ListToDataTable(goodDrugCodeLists);
            string tableName = "表名";
            BulkToDB(dt, tableName);

問題

注意啊,本文我引用的是Oracle.DataAccess.dll,大家可知道引用Oracle的這個dll帶來的問題是什麼???

    要使用Oracle.DataAccess.dll,在使用的機子上必須安裝Oracle的客戶端,你說坑不坑,為了減少實施團隊的工作量,在我正高興的時候,技術主管告訴我,這個方法不能用,瞬間覺得好心塞。而且我們的系統為了杜絕使用Oracle.DataAccess.dll,直接把其中的connection方法遮蔽了,就算你安裝了Oracle客戶端,也調不通!!!

    在坑貨下面必然還有別的方法替代,果不其然,小編找到了新的方法,還請我們技術主管幫小編封裝了一下,變成公共的方法,方便大家使用。瞬間覺得技術主管也不是那麼高冷,關於具體的封裝,見下篇部落格。

總結

    沒事就多嘗試一下,必然會有更好的方法替代,千萬別放棄,沒事多和技術大牛交流,站在巨人的肩膀上啊。這可是老師教的!哈哈,還是要說,允許引用Oracle.DataAccess.dll,這個方法還是非常可取的,而且在sqlserver,MySQL中都有類似的方法。