深入探討C#文字連接
[[academy-video-youtube({"vid": "WGbTM198-eA", "start_time": "0", "title": "C# App Start To Finish Lesson 10 - SQL Connection", "creator": "Tim Corey", "length": "1h 15m 23s"})]]
在Tim Corey的《C# App從頭開始》系列的第11課中,Tim解釋了如何使用基於文字的資料連接將資料保存到文字文件中。 Tim開場便提醒觀眾在上一課中,他們已經設置了SQL連接並執行了關鍵的基本維護任務。 現在,重點轉向文字連接,目標很明確:讓文字連接像SQL連接一樣工作,系統可以採用PrizeModel並以正確填寫ID的方式返回它。 Tim強調這個影片將展示完整的工作流程,如何使用純文字文件儲存、讀取和更新資料。
解決方案——設置文字連接
Tim從打開DataAccess文件夾中的Text Connector開始。 他刪除了範例程式碼並從頭開始。 他解釋說,與SQL不同,文字文件不提供智能的資料庫功能,如自動增量ID。 所以第一個任務是決定在何處儲存文字文件。
Tim建議一個乾淨的設計:把每個模型儲存在自己的文字文件中。例如,PrizeModel將有自己的文件,名為PrizeModels.csv,而其他模型,如MatchupModel,也會有各自的文件。 Tim將此結構比做SQL表——每個文件成為包含該模型列表的"表"。 這讓資料易於管理,防止不同模型型別混合在一起。
連接字串——儲存文件路徑
Tim解釋說,您應該儲存一個路徑,而不是僅儲存單個文件名,這個路徑指向所有文件將被保存的資料夾。 這個路徑放置在app.config的appSettings部分。 Tim增加了一個新的鍵-值對:
鍵:filePath
- 值:文件將被儲存的資料夾路徑
他強調使用正確的Windows語法,並避免路徑以斜杠結尾,因為他更喜歡在構建完整的文件路徑時才加上斜杠。 這種設置很重要,因為它使應用程式具有靈活性——即使儲存位置發生改變,您只需更新app.config即可。
計劃——文字連接如何工作
Tim為儲存獎項概述了一個清晰的計劃:
載入包含所有獎項的文字文件。
將文字行轉換為PrizeModel列表。
在列表中查找最高ID並將新ID設為最高ID + 1。
將新的獎項模型新增到列表中。
將獎項列表轉換回文字行。
- 將列表保存回文字文件,覆蓋舊資料。
Tim解釋說,與SQL資料庫相比,文字文件是"愚蠢的"。 SQL可以自動管理ID,而文字文件需要開發者手動實現邏輯。 這就是為什麼Tim將過程分解為較小的方法,以保持程式碼簡潔和可重用。
建立新類——文字連接處理器
Tim建立了一個名為TextConnectorProcessor的新類。 他將其放置在DataAccess文件夾中,但在不同的命名空間中,以避免使主命名空間變得混亂。 Tim解釋說命名空間是靈活的,可以自定義,但他建議保持簡單和清晰。
他將類設為public static,並開始構建輔助方法。
擴展方法——完整文件路徑
Tim建立了一個擴展方法:
public static string FullFilePath(this string fileName)此方法將app.config中的filePath與文件名結合起來生成完整的文件路徑。 Tim演示如何使用ConfigurationManager.AppSettings["filePath"],並解釋了在C#字串中逃逸斜線(使用\)的必要性。
然後他將方法轉換為擴展方法,以便可以這樣使用:
"PrizeModels.csv".FullFilePath()Tim解釋說,這個擴展方法只在文字連接中需要,所以他把它放在一個單獨的命名空間中,以避免在解決方案的任何地方顯示它。
載入文件方法——讀取文字資料
然後,Tim建立了另一個擴展方法:
public static List<string> LoadFile(this string file)此方法使用File.Exists()檢查文件是否存在。 如果文件不存在,它將返回一個空列表。如果文件存在,它將使用File.ReadAllLines()讀取所有行並將其轉換為列表。
Tim強調正確處理丟失的文件的重要性,因為這在應用程式的第一次運行中很常見。
將文字轉換為獎品模型
Tim建立了一個方法來將載入的文字行轉換為PrizeModel列表:
public static List<PrizeModel> ConvertToPrizeModels(this List<string> lines)他解釋使用逗號分隔值(CSV),每行包含用逗號分隔的字段。 Tim將每行拆分為列並將其解析為適當的資料型別:
ID → int.Parse()
PlaceNumber → int.Parse()
PlaceName → string
PrizeAmount → decimal.Parse()
- PrizePercentage → double.Parse()
Tim還解釋說,他故意允許應用程式崩潰,如果資料無效。 這有助於及早發現問題,而不是繼續使用已損壞的資料。
查找最大ID
Tim回到TextConnector,解釋如何找到最高的ID:
int currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;他指出如果文件為空將會崩潰,所以他加了一個檢查:
if(prizes.Count > 0)
{
currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;
}這確保了第一條記錄獲得ID為1。
新增模型並保存
Tim將新的獎品新增到列表中,然後將列表轉回文字行:
public static void SaveToPrizeFile(this List<PrizeModel> models, string fileName)他使用字串插值建立每個CSV行並將其新增到字串列表中。 最後,他使用:
File.WriteAllLines(fileName.FullFilePath(), lines);Tim解釋說,WriteAllLines會覆蓋文件,這是一種期望的行為,因為它用更新的內容刷新了資料。
返回模型
Tim結束該方法並返回帶有分配ID的PrizeModel。 這讓新的獎品可以在應用程式的其他地方使用,就像SQL一樣。
測試文字連接
Tim切換到Program.cs,並將資料連接從SQL改為文字。 當他運行應用程式並建立獎品時,系統因記錄丟失而最初崩潰。 Tim快速修復了使用if(prizes.Count > 0)檢查的錯誤,然後再次運行。
他演示了資料被正確保存到PrizeModels.csv文件中,並顯示了如何在記事本或Excel中打開文件。
最後的想法——擴展方法和命名空間
Tim在課程中結束時提醒觀眾,擴展方法僅在包含正確的命名空間時顯示。 這避免了混亂和潛在的命名衝突。 他指出,這兩個課程為應用程式的其餘部分創造了一個強大的基礎,並為未來的開發奠定了基礎。

