用于在平面文件中对字段进行分组和结构化数据的设计模式

本文关键字:结构化 数据 设计模式 平面文件 字段 用于 | 更新日期: 2023-09-27 18:30:14

我正在使用FileHelpers C#库将文件读取到将要处理的自定义对象数组中。例如,部分文件定义:

[FixedLengthRecord]
public class Row
{
    [FieldFixedLength(9)]
    [FieldTrim(TrimMode.Right)]
    public string Ssn;
    [FieldFixedLength(15)]
    [FieldTrim(TrimMode.Right)]
    public string LastName;
    ...
}

在做这件事的时候,我试图遵守OOP原则,我注意到一些字段有一个自然的分组(例如SSNClientIDEmployerIDEmployerName等),所以我试图将它们分解为单独的类(例如ClientEmployer)。但这似乎有问题,因为一些字段需要在对象之间共享(例如,ClientID需要知道关联的EmployerID)。

更复杂的是,我想将具有[FieldNotInFile]属性的字段添加到类定义中,因为在处理过程中,我的应用程序将查询与特定行字段匹配的数据库记录,并填充该行各自的[FieldNotInFile](例如,基于SSN从数据库中获取客户端的FName,因为它不在文件中)。

你会如何构建它?我只是想把整个文件行作为一个类,但它已经接近75个字段,这似乎很荒谬。想法?

用于在平面文件中对字段进行分组和结构化数据的设计模式

FileHelpers类只是使用C#语法定义平面文件规范的一种方法。

因此,FileHelpers类是一种不寻常的C#类,您应该而不是尝试使用公认的OOP原则。(FileHelpers类在很多方面违反了OOP原则,最明显的是它要求您使用公共字段而不是属性)。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类将是一个适当的OOP类,根据需要具有属性、方法等。

我不确定具体的模式,但我不会在用于反序列化/解析平面文件的类中包含额外的字段。您可以将数据库字段添加到继承的类中。

在使用文件帮助程序时,我认为FileHelper类表示文件中的记录。放在类顶部的属性(FixedLengthRecord或DelimitedRecord)提醒您注意这一点——这是一个文件记录,而不是实际实体的模型。

这意味着,如果您需要一个为实体建模的对象,则必须从FileHelper类向实体类进行大量复制。

我有很多FileHelper类,大约有75个字段——每个类都代表一个文件规范,这个规范通常很大。但这些仍然是非常可维护的——只需并排打开规范和代码文件,然后在字段列表中查找需要进行的任何更改。

然而,我会为标题、尾部和不同的行类型划分类。然后我会使用MultiRecord引擎来决定使用哪个类。