Głębokie wejście w połączenie tekstowe C#
W lekcji 11 serii "C# App Start to Finish" Tima Corey'a, Tim wyjaśnia, jak zapisywać dane w plikach tekstowych używając połączenia danych opartego na tekście. Tim rozpoczyna od przypomnienia widzom, że w poprzedniej lekcji skonfigurowali połączenie SQL i wykonali kluczowe zadania porządkowe. Teraz uwaga jest skierowana na Połączenie Tekstowe, a cel jest jasny: sprawić, by połączenie tekstowe działało jak połączenie SQL, gdzie system może pobrać PrizeModel i zwrócić go z prawidłowo uzupełnionym ID. Tim podkreśla, że wideo pokaże kompletny przepływ pracy do przechowywania, czytania i aktualizacji danych za pomocą zwykłych plików tekstowych.
Rozwiązanie — Konfiguracja Połączenia Tekstowego
Tim zaczyna od otwarcia Text Connector w folderze DataAccess. Usuwa przykładowy kod i zaczyna od nowa. Wyjaśnia, że w przeciwieństwie do SQL, pliki tekstowe nie oferują inteligentnych funkcji bazy danych, takich jak automatyczne zwiększanie ID. Zatem pierwszym zadaniem jest zdecydowanie, gdzie przechowywać pliki tekstowe.
Tim proponuje przejrzysty projekt: przechowywać każdy model w jego własnym pliku tekstowym. Na przykład, PrizeModel będzie miał własny plik o nazwie PrizeModels.csv, podczas gdy inne modele, takie jak MatchupModel, będą miały oddzielne pliki. Tim porównuje tę strukturę do tabel SQL — każdy plik staje się "tabelą" zawierającą listę tego modelu. Ułatwia to zarządzanie danymi i zapobiega mieszaniu różnych typów modeli.
Ciąg Połączenia — Przechowywanie Ścieżki Pliku
Tim wyjaśnia, że zamiast przechowywać pojedynczą nazwę pliku, przechowujesz ścieżkę do folderu, gdzie będą zapisane wszystkie pliki. Ta ścieżka jest umieszczona w app.config pod appSettings. Tim dodaje nową parę klucz-wartość:
-
Klucz: filePath
- Wartość: ścieżka folderu, w którym będą przechowywane pliki
Podkreśla użycie poprawnej składni Windows i unikanie kończenia ścieżki slashem, ponieważ woli dodawać slash tylko podczas tworzenia pełnej ścieżki pliku. To ustawienie jest kluczowe, ponieważ czyni aplikację elastyczną — jeśli lokalizacja przechowywania się zmieni, wystarczy zaktualizować app.config.
Plan — Jak Działa Połączenie Tekstowe
Tim przedstawia jasny plan dla zapisywania nagrody:
-
Załaduj plik tekstowy zawierający wszystkie nagrody.
-
Konwertuj wiersze tekstu na listę PrizeModel.
-
Znajdź najwyższe ID na liście i ustaw nowe ID = najwyższe ID + 1.
-
Dodaj nowy model nagrody do listy.
-
Konwertuj listę nagród z powrotem na wiersze tekstu.
- Zapisz listę z powrotem do pliku tekstowego, nadpisując stare dane.
Tim wyjaśnia, że w porównaniu do baz danych SQL, pliki tekstowe są "głupie". SQL może automatycznie zarządzać ID, ale pliki tekstowe wymagają ręcznego wdrożenia logiki przez programistę. Dlatego Tim dzieli proces na mniejsze metody, aby utrzymać kod czysty i wielokrotnie używalny.
Tworzenie nowej klasy — Text Connector Processor
Tim tworzy nową klasę o nazwie TextConnectorProcessor. Umieszcza ją w folderze DataAccess, ale w innej przestrzeni nazw, aby nie zaśmiecać głównej przestrzeni nazw. Tim wyjaśnia, że przestrzenie nazw są elastyczne i mogą być dostosowywane, ale zaleca utrzymanie ich prostych i czystych.
Czyni klasę public static i zaczyna tworzyć metody pomocnicze.
Metoda rozszerzająca — Pełna ścieżka pliku
Tim tworzy metodę rozszerzającą:
public static string FullFilePath(this string fileName)
Ta metoda łączy filePath z app.config z nazwą pliku, aby wygenerować pełną ścieżkę pliku. Tim demonstruje, jak używać ConfigurationManager.AppSettings("filePath") i wyjaśnia konieczność ucieczki ukośników w ciągach C# używając \\.
Następnie konwertuje metodę na metodę rozszerzającą, aby mogła być używana w ten sposób:
"PrizeModels.csv".FullFilePath()
Tim wyjaśnia, że ta metoda rozszerzająca jest potrzebna tylko w złączu tekstowym, więc trzyma ją w osobnej przestrzeni nazw, aby nie była widoczna wszędzie w rozwiązaniu.
Metoda ładowania plików — Odczytywanie danych tekstowych
Następnie Tim tworzy kolejną metodę rozszerzającą:
public static List<string> LoadFile(this string file)
Ta metoda sprawdza, czy plik istnieje, używając File.Exists(). Jeśli plik nie istnieje, zwraca pustą listę. Jeśli istnieje, odczytuje wszystkie linie używając File.ReadAllLines() i konwertuje je na listę.
Tim podkreśla znaczenie właściwego obsługiwania brakujących plików, ponieważ jest to powszechne podczas pierwszego uruchomienia aplikacji.
Konwertowanie tekstu na modele nagród
Tim tworzy metodę do przekształcenia załadowanych linii tekstu na listę PrizeModel:
public static List<PrizeModel> ConvertToPrizeModels(this List<string> lines)
Wyjaśnia użycie wartości rozdzielonych przecinkami (CSV), gdzie każdy wiersz zawiera pola oddzielone przecinkami. Tim dzieli każdą linię na kolumny i analizuje je na odpowiednie typy danych:
-
ID → int.Parse()
-
PlaceNumber → int.Parse()
-
PlaceName → string
-
PrizeAmount → decimal.Parse()
- PrizePercentage → double.Parse()
Tim również wyjaśnia, że celowo pozwala aplikacji na awarię, jeśli dane są niewłaściwe. Pomaga to ujawniać problemy wcześniej, zamiast kontynuować z uszkodzonymi danymi.
Znajdowanie maksymalnego ID
Tim wraca do TextConnector i wyjaśnia, jak znaleźć najwyższe ID:
int currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;
Zauważa, że to spowoduje awarię, jeśli plik jest pusty, więc dodaje sprawdzenie:
if(prizes.Count > 0)
{
currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;
}
Zapewnia to, że pierwszy rekord otrzyma ID 1.
Dodawanie modelu i zapisywanie
Tim dodaje nową nagrodę do listy, a następnie przekształca listę z powrotem na wiersze tekstu:
public static void SaveToPrizeFile(this List<PrizeModel> models, string fileName)
Używa interpolacji ciągów do tworzenia każdej linii CSV i dodaje ją do listy ciągów. Na koniec używa:
File.WriteAllLines(fileName.FullFilePath(), lines);
Tim wyjaśnia, że WriteAllLines nadpisuje plik, co jest pożądanym zachowaniem, ponieważ odświeża dane z zaktualizowaną treścią.
Zwrot modelu
Tim kończy metodę, zwracając PrizeModel z przypisanym ID. Dzięki temu nowa nagroda jest użyteczna w reszcie aplikacji, tak jak SQL.
Testowanie połączenia tekstowego
Tim przełącza się na Program.cs i zmienia połączenie danych z SQL na Text. Gdy uruchamia aplikację i tworzy nagrody, system początkowo pada z powodu brakujących rekordów. Tim szybko naprawia błąd sprawdzaniem if(prizes.Count > 0), a następnie ponownie uruchamia.
Demonstruje, że dane są poprawnie zapisywane do pliku PrizeModels.csv i pokazuje, jak plik można otworzyć w Notatniku lub Excelu.
Ostateczne uwagi — Metody rozszerzeń i przestrzenie nazw
Tim kończy lekcję przypominając widzom, że metody rozszerzeń pojawiają się tylko wtedy, gdy odpowiednia przestrzeń nazw jest dołączona. To zapobiega zagraceniu i potencjalnym konfliktom nazw. Zaznacza, że te dwie lekcje tworzą solidne fundamenty dla reszty aplikacji i przygotowują do przyszłego rozwoju.
