Я использую библиотеку FileHelpers С# для чтения файла в массив настраиваемых объектов, которые будут обработаны. Например, определение частичного файла:
[FixedLengthRecord]
public class Row
{
[FieldFixedLength(9)]
[FieldTrim(TrimMode.Right)]
public string Ssn;
[FieldFixedLength(15)]
[FieldTrim(TrimMode.Right)]
public string LastName;
...
}
Я стараюсь придерживаться принципов ООП при этом, и я заметил, что некоторые поля имеют естественную группировку (например, SSN
и ClientID
, EmployerID
и EmployerName
и т.д.), Поэтому я попытался разбить их на отдельные классы (например, Client
и Employer
). Но это кажется проблематичным, потому что некоторые из полей должны быть разделены между объектами (например, ClientID
должен знать соответствующий EmployerID
).
Чтобы еще больше усложнить ситуацию, я хотел бы добавить поля с атрибутом [FieldNotInFile]
к определениям классов, потому что во время обработки мое приложение будет запрашивать записи базы данных, соответствующие определенному полю строки, и заполнять соответствующую строку [FieldNotInFile]
( например, получить имя клиента FName
из базы данных на основе SSN
поскольку оно не находится в файле).
Как бы вы это структурировали? Я вроде как хочу сохранить всю строку файла как один класс, но она приближается к 75 полям, что кажется смешным. Мысли?
Класс FileHelpers - это просто способ определения спецификации плоского файла с использованием синтаксиса С#.
Таким образом, классы FileHelpers являются необычным типом класса С#, и вы не должны пытаться использовать принятые принципы ООП. (Существует много способов, по которым класс FileHelpers нарушает принципы ООП, наиболее очевидно, что он требует использования открытых полей вместо свойств). FileHelpers не должны иметь свойств или методов, кроме тех, которые используются библиотекой FileHelpers.
Представьте, что класс FileHelpers является "спецификацией" вашего формата CSV. Это должна быть его единственная роль. Затем, если вам нужны записи в более "нормальном" объекте, тогда сопоставьте результаты с чем-то лучшим:
FileHelperEngine engine = new FileHelperEngine<FileHelpersOrder>();
var records = engine.ReadFile("FileIn.txt");
var niceOrders = records.Select(
x => new NiceOrder()
{ Number = x.Number,
Customer = x.Customer
// etc.
});
Если FileHelpersOrder
является вашей спецификацией CSV, а класс NiceOrder
будет подходящим классом ООП со свойствами, методами и т.д. По мере необходимости.
В использовании файловых помощников я считаю класс FileHelper представлять запись в файле. Атрибут, который вы помещаете в начало класса (FixedLengthRecord или DelimitedRecord), напоминает вам об этом - это запись файла, а не модель фактического объекта.
Это означает, что если вам нужен объект, который моделирует сущность, вам нужно будет сделать много копий из класса FileHelper в ваш класс сущностей.
У меня много классов FileHelper с примерно 75 полями - каждый из этих классов представляет собой спецификацию файла, которая часто бывает большой. Но они по-прежнему очень удобны в обслуживании - просто откройте спецификацию и файл кода рядом и опустите список полей, чтобы найти какие-либо изменения, которые вам нужно внести.
Однако я разделил классы для заголовков, трейлеров и разных типов строк. Затем я бы использовал механизм MultiRecord, чтобы решить, какой класс использовать.
Я не уверен в определенном шаблоне, но я не буду включать дополнительные поля в класс, предназначенные для десериализации/анализа вашего плоского файла. Вы можете добавить поле базы данных в унаследованный класс.