Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
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還解釋說,他故意允許應用程式崩潰,如果資料無效。 這有助於及早發現問題,而不是繼續使用已損壞的資料。
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在課程中結束時提醒觀眾,擴展方法僅在包含正確的命名空間時顯示。 這避免了混亂和潛在的命名衝突。 他指出,這兩個課程為應用程式的其餘部分創造了一個強大的基礎,並為未來的開發奠定了基礎。
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy