Получение данных из внешних источников. CSV.
April 29, 2024 · View on GitHub
-
Для начала создаём файл с данными для импорта. Я продолжаю тему кошек, вы реализуете свою предметную область:
Мы должны уметь работать с разными типами данных, поэтому я добавил в исходные данные тип Date (дата прививки). Формат даты имеет множество разных форматов, но при экспорте обычно используют SQL формат (
yyyy-mm-dd)age,breed,color,name,photo,dateOfLastVaccination 1,"Дворняжка","Белый","Ириска",,2024-04-29 2,"Шотландская вислоухая","Коричневый","Изи",,2020-01-31 3,"Сиамский","Цветной","Макс",,2022-05-10- в первой строке названия полей, соответствующие модели данных
- разделитель запятая
- строковые литералы (текст, в котором могут встретиться спец.символы, а лучше все текстовые поля) заключаем в двойные кавычки
- для отсутствующих полей (у меня
photo) оставляем пустую строку
Файл сохраняем в подкаталог
bin/debug/net8.0-windowsвашего проекта - туда, где создается исполняемый (.exe) файл (название зависит от версии .NET и платформы). -
Правим модель (у нас добавилось свойство "Дата последней прививки")
public class Cat { public string name { get; set; } public int age{ get; set; } public string color { get; set; } // порода public string breed { get; set; } public string photo { get; set; } // новое свойство public DateOnly dateOfLastVaccination { get; set; } } -
Загружаем данные из файла в класс поставщика данных
Тут есть два варианта: либо каждый раз загружать данные при вызове метода getCats, либо загрузить один раз при создании экземпляра класса (в конструкторе). Оба варианта имеют право на жизнь: первый имеет смысл применять, если данные часто меняются, второй, если данные статичны. Я реализую второй вариант.
Вспоминаем материалы лекции про типы данных и создаём для работы с CSV файлами класс CSVDataProvider, реализующий интерфейс IDataProvider:
-
Создаём приватную переменную для хранения загруженного списка и считываем данные в конструкторе:
Библиотека CsvHelper достаточно "умная" и преобразует строку в дату автоматически
Но в то же время они и "слишком умная", если данные не соответсвуют модели (не хватает полей) или типу (например, в дате нет времени), то запись игнорируется
public class SCVDataProvider : IDataProvider { private List<Cat> catList; // конструктор класса public CSVDataProvider() { using (var reader = new StreamReader("./cat.csv")) { using (var csv = new CsvReader( reader, CultureInfo.InvariantCulture)) { // CsvHelper использует отложенное чтение через // yeld, поэтому сразу преобразуем в список catList = csv.GetRecords<Cat>().ToList(); } } } } -
реализуем интерфейс IDataProvider (пишем метод getCats):
public IEnumerable<Cat> getCats() { return catList; }
-
-
Теперь в конструкторе окна меняем класс провайдера и всё продолжает работать
public MainWindow() { InitializeComponent(); DataContext = this; // Globals.dataProvider = new LocalDataProvider(); Globals.dataProvider = new CSVDataProvider(); CatList = Globals.dataProvider.getCats(); }
ЗАДАНИЕ
-
Подготовить набор данных (не менее 10 записей) с разными типами (обязательно должны быть: Int, Double, String, DateTime, Boolean)
-
Реализовать класс CSVDataProvider для своей предметной области
-
Поле с датой добавить в таблицу и указать формат вывода:
Binding="{Binding YourColumn,StringFormat='dd.MM.yyyy'}"