接上期
dataset簡而言之可以理解為 虛擬的 資料庫或是Excel檔案,而dataset里的datatable 可以理解為資料庫中的table活著Excel里的sheet(Excel里面不是可以新建很多表嗎),
這樣說應該很容易懂了,相當于dataset只是暫時存放下資料,微軟官方解釋是存在記憶體中,至于為啥要找個“中介”來存資料,這個估計是為了和SQL匹配,
好了,接下來說下這次的重點,
在把Excel的資料存到dataset后,我們要把dataset的資料存入SQL才算完事,
廢話不多說先上后面的代碼:(總的代碼)
using System.IO; using System.Data; using System.Configuration; using System.ServiceProcess; using System.Data.SqlClient; using System.Data.OleDb; using System.Timers;using System; namespace DataCollection_model_HD { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); InitTimer(); } #region 各種配置的全域定義 //定義一個dataset 用于暫時存放excel中的資料,后續要存入datatable DataSet ds = new DataSet(); Timer TimModel = new Timer(); public static string LogPath = ConfigurationManager.AppSettings["LogPath"].ToString(); public static string WPath = ConfigurationManager.AppSettings["WorkingPath"].ToString(); public static string APath = ConfigurationManager.AppSettings["ArchivePath"].ToString(); //資料庫登錄 //注意Integrated Security不寫(false)表示必須要用pwd登錄,true表示不用密碼也能進入資料庫 public static string ConnStr = ConfigurationManager.AppSettings["ConnStr"].ToString(); //用于記錄log的時候,機臺名字 public static string machineName = "test"; #endregion #region 定時器的初始化,及其事務 //這個按鈕用于模擬服務(定時器)啟動 public void InitTimer() { //DFL的定時器 TimModel.Interval = 15 * 1000; //定時器的事務 TimModel.Elapsed += new ElapsedEventHandler(ElapsedEventDFL); TimModel.Enabled = true; TimModel.AutoReset = true; } private void ElapsedEventDFL(object source, ElapsedEventArgs e) { if (GetFiles("test")) { //多次讀取資料,存在多個檔案時但其中某個檔案在使用的bug ds.Tables.Clear(); Log4App.WriteLine(" ---- End the collect ! ----", LogPath, machineName, System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(), Log4AES.Type.Information); } else { DataToSql("test"); BackupData("test"); Log4App.WriteLine(" ---- End the collect ! ----", LogPath, machineName, System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(), Log4AES.Type.Information); } } #endregion //log初始化設定 Log4Application Log4App = new Log4Application(); /*用于移動源檔案到指定檔案夾,也就是備份源資料檔案 copy all file in folder Working to Achieve*/ public void BackupData(string equipName) { //需要存放(備份)的檔案夾路徑(Achieve) string ArchivePath = APath + equipName + " Equipment Temp. monitoring by third tool\\Archive"; //讀取資料源檔案的檔案夾路徑(Working) string WorkingPath = WPath + equipName + " Equipment Temp. monitoring by third tool\\Working"; //初始化system.IO的配置(路徑) DirectoryInfo directoryInfo = new DirectoryInfo(WorkingPath); //用檔案流來獲取檔案夾中所有檔案,存放到 FileInfo[] files = directoryInfo.GetFiles(); //回圈的把所有機臺資料備份到Achieve檔案夾 try { foreach (FileInfo file in files) // Directory.GetFiles(srcFolder) { //使用IO中的Moveto函式進行移動檔案操作 file.MoveTo(Path.Combine(ArchivePath, file.Name)); } } catch (Exception ex) { } } //判斷Excel是否在被人使用 public bool IsUsed(String fileName) { bool result = false; try { FileStream fs = File.OpenWrite(fileName); fs.Close(); } catch { result = true; } return result; } //將xls檔案投入datatable , 回傳一個datatable為 ds.table[0] public bool GetFiles(string equipName) { bool flag = false; //choose all sheet? or all data in sheet? string strExcel = "select * from [Sheet1$]"; //初始化system.IO的配置(路徑) DirectoryInfo directoryInfo1 = new DirectoryInfo(WPath + equipName + " Equipment Temp. monitoring by third tool\\Working"); //用檔案流來獲取檔案夾中所有檔案,存放到 FileInfo[] files1 = directoryInfo1.GetFiles(); foreach (FileInfo file in files1) // Directory.GetFiles(srcFolder) { // 連接到excel 資料源, xlsx要用ACE string strConn = ("Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source= " + file.FullName + "; Extended Properties='Excel 12.0';"); OleDbConnection OledbConn = new OleDbConnection(strConn); if (IsUsed(file.FullName)) { flag = IsUsed(file.FullName); continue; } try { OledbConn.Open(); // 存入datatable,Excel表示哪一個sheet,conn表示連接哪一個Excel檔案(jet、ACE) OleDbDataAdapter dAdapter = new OleDbDataAdapter(strExcel, strConn); dAdapter.Fill(ds); OledbConn.Dispose(); OledbConn.Close(); } catch (Exception ex) { } } return flag; } // 將datatable中的資料存入SQL server public void DataToSql(string equipName) { //初始化配置 sqlserver的服務器名用戶等 SqlConnection Conn = new SqlConnection(ConnStr); Conn.Open(); //配置SQLBulkCopy方法,真正用于復制資料到資料庫的方法 SqlBulkCopy bulkCopy = new SqlBulkCopy(ConnStr, SqlBulkCopyOptions.UseInternalTransaction) { DestinationTableName = "ModelTest_HD" }; try { foreach (DataColumn item in ds.Tables[0].Columns) { //只復制所選的相關列 bulkCopy.ColumnMappings.Add(item.ColumnName, item.ColumnName); } //開始復制到sql,每次在資料庫中添加 bulkCopy.WriteToServer(ds.Tables[0]); bulkCopy.Close(); //copy完了,要清空ds的內容,不然會引起回圈寫入上一個內容 ds.Tables.Clear(); } catch (Exception ex) { } finally { //關閉資料庫通道 Conn.Close(); } } protected override void OnStart(string[] args) { //啟動服務時做的事情 } protected override void OnStop() { //停止服務時做的事情 } } }
認真看注釋可以看出本程式的邏輯就是:
1、讀取到Excel資料
2、存Excel資料到SQL server
3、備份Excel檔案到另一個檔案夾
其中一些功能大家可以看一看,注釋也寫的很清楚,對于初學者 configurationmanager的內容是在 app.config中設定的,這里直接去配置就行(類似html)
不 懂可以評論問樓主,
接下來就是重要的SQLBulkCopy了:
foreach (DataColumn item in ds.Tables[0].Columns)
{
//只復制所選的相關列
bulkCopy.ColumnMappings.Add(item.ColumnName, item.ColumnName);
}
注意這一段代碼,表示只復制資料庫與Excel表中 “列名”一致的資料,如果不一致就不復制,(注意資料的格式,int還char 這些必須弄清楚)
然后bulkCopy.WriteToServer(ds.Tables[0])這里,就是把ds.tables的資料復制到SQLserver ,Tables[0]表示ds第一張表(其實我們也只有一張表,至于怎么在dataset中新建table自己可以查查資料)
最后的最后,注意釋放這些dataset,或者table,然后通道也記得close一下,
祝大家學習快樂,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/266554.html
標籤:C#
上一篇:理解C#泛型運作原理
