最近一直在用,也一直在學oralc,項目上也用到了批量的添加(讀取上傳CSV文件信息,把符合條件的信息寫入到資料庫中),在寫的時候想到了可能是數據量大就想該怎麼快,(由於本人在.NET開發期間沒有做過深度的優化) 上傳CSV文件有專門的方法,只要複製進去就好了 上傳完成的CSV文件返回的DataTa ...
最近一直在用,也一直在學oralc,項目上也用到了批量的添加(讀取上傳CSV文件信息,把符合條件的信息寫入到資料庫中),在寫的時候想到了可能是數據量大就想該怎麼快,(由於本人在.NET開發期間沒有做過深度的優化)
1 private string GUID;//序號GUID唯一標識 2 private string filename;//文件名稱 3 private string lmportl_ID;//導入ID 4 private Int32? lmportl_date;//導入時間 5 private string diflag;// 國際/國內標識 DIFlag
上傳CSV文件有專門的方法,只要複製進去就好了
#region 將CSV文件的數據讀取到DataTable中 /// <summary> /// 將CSV文件的數據讀取到DataTable中 /// </summary> /// <param name="fileName">CSV文件路徑</param> /// <returns>返回讀取了CSV數據的DataTable</returns> public static DataTable OpenCSV(string filePath) { DataTable dt = new DataTable(); FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); StreamReader sr = new StreamReader(fs, Encoding.UTF8); //StreamReader sr = new StreamReader(fs, encoding); //string fileContent = sr.ReadToEnd(); //記錄每次讀取的一行記錄 string strLine = ""; //記錄每行記錄中的各欄位內容 string[] aryLine = null; string[] tableHead = null; //標示列數 int columnCount = 0; //標示是否是讀取的第一行 bool IsFirst = true; //逐行讀取CSV中的數據 while ((strLine = sr.ReadLine()) != null) { if (IsFirst == true) { tableHead = strLine.Split(','); if (tableHead.Length > 3) //截取列數 tableHead = tableHead.Skip(0).Take(3).ToArray(); IsFirst = false; columnCount = tableHead.Length; //創建列 for (int i = 0; i < columnCount; i++) { tableHead[i] = tableHead[i].Replace("\"", ""); DataColumn dc = new DataColumn(tableHead[i]); dt.Columns.Add(dc); } } else { aryLine = strLine.Split(','); if (aryLine.Length > 3) aryLine = aryLine.Skip(0).Take(3).ToArray(); DataRow dr = dt.NewRow(); //是否超過1000行 if (dt.Rows.Count <= 1000) { //Prefix和FormType字元串長度是否超過3 if (aryLine[0].Length <= 3 && aryLine[1].Length <= 3) { dr[0] = aryLine[0].Replace("\"", ""); dr[1] = aryLine[1].Replace("\"", ""); } else { dr[0] = aryLine[0].Substring(0, 3); dr[1] = aryLine[1].Substring(0, 3); } //TicketNo 字元串長度是否超過8 if (aryLine[2].Length <= 8) { dr[2] = aryLine[2].Replace("\"", ""); } else { dr[2] = aryLine[2].Substring(0, 8); } } else { return dt;//跳出程式,行數大於1000,不做添加, } dt.Rows.Add(dr); } } if (aryLine != null && aryLine.Length > 0) { dt.DefaultView.Sort = tableHead[2]; } sr.Close(); fs.Close(); return dt; } #endregion
上傳完成的CSV文件返回的DataTable 我需要把DataTable 轉貨成List,我們用的EF所以可以直接轉換
DataEnt = DataConvertor.GetEntityList<t>(dtb) as List<T>;
把List傳入方法中
#region 插入票號轉換數據到表 /// <summary> /// 插入票號轉換數據到表 /// </summary> /// <param name="">表的實體</param> /// <returns></returns> public BaseEntityJsonObject<int> Insert_TRANSFER(List<T> T) { BaseEntityJsonObject<int> result = new BaseEntityJsonObject<int>(); int count = 0; string strSql = ""; try { StringBuilder strBuilder = new StringBuilder(); strBuilder.Append("INSERT INTO 表名( 欄位明,欄位明,欄位明) "); strBuilder.Append("select sequence_name.nextval ,t.c1,t.c2,t.c3,t.c4,t.c5 FROM ( "); foreach (var item in T) { strBuilder.Append(" SELECT "); strBuilder.Append("'" + item.欄位名+ " 'C1,'" + item.欄位名+ " 'C2,'" + item.欄位名+ "' C3,"); strBuilder.Append("'欄位名' C4 ,'" + 欄位名+ "' C5 FROM DUAL union all "); } strBuilder.Append(" ) T"); strSql = string.Format(strBuilder.ToString()); int i = 14; //sql寫完後這裡嘚坐sql的截取,要不然會報錯 strSql = strSql.Remove(strSql.Length - i, 11); count = DbContext.Database.ExecuteSqlCommand(strSql); } catch (Exception ex) { ExceptionHandler.HandleException(ex); } return result; } #endregion
這就是添加!
下麵寫批量修改
寫修改前先要把要修稿的數據查詢出來,轉貨成LIst,我就不說怎麼查詢,怎麼轉貨List了
我這裡寫的流程是先把List寫進資料庫的視圖中,然後數據插進偽表中 然後根據偽表中的數據做進一步的條件,不說了,直接上代碼
#region 修改轉換數據到表 /// <summary> /// 修改轉換數據到表 /// </summary> /// <param name="">表的實體</param> /// <returns></returns> public BaseEntityJsonObject<int> Update_TRANSFER(List<T> T) { BaseEntityJsonObject<int> result = new BaseEntityJsonObject<int>(); int count = 0; string strSql = ""; try { StringBuilder strBuilder = new StringBuilder(); strBuilder.Append(" MERGE INTO TRT_TICKETNUMBER_TRANSFER T1 USING ( "); //從這裡迴圈要修改的數據,把數據先臨時放到偽表中 foreach (var item in t) { strBuilder.Append(" SELECT '" + item.要修改的欄位名+ "' a, '" + item.要修改的欄位名+ "' b FROM DUAL t "); strBuilder.Append(" union all "); } string str2 = strBuilder.ToString(); if (str2 != "") { str2 = str2.Remove(str2.Length - 10); } //把sql進行截取,要不然會報錯,然後在拼接SQL語句 StringBuilder strBuilder2 = new StringBuilder(); strBuilder2.Append(" ) T2 ON ( T1.表中的主鍵欄位 = T2.a 臨時表的欄位 ) "); strBuilder2.Append(" WHEN MATCHED THEN "); strBuilder2.Append(" UPDATE SET T1.需要修改的欄位名 = t2.b"); strSql = str2 + strBuilder2.ToString(); count = DbContext.Database.ExecuteSqlCommand(strSql); result.payload = count; result.errorCode = 0; } catch (Exception ex) { ExceptionHandler.HandleException(ex); LogHelper.Error(string.Format("添加表數據失敗"), ex); } return result; } #endregion
這樣就完成了數據的修改,
由於臨時想起來寫博客,沒有準備充分,
有什麼不妥的歡迎大家指出,歡迎大家吧問題指出來,然後大家共同進步