FileHelpers - Subclassing with FixedLengthRecords

235 Views Asked by At

I am working with a file which has multiple possible permutations of line format depending on an element subject to change. All permutations share length, the difference lies in elements being filled/empty depending on record type.      If we consider the following class:  

 
[FixedLengthRecord(FixedMode.ExactLength)]
    public class FixedLengthRecord
    {
        
        [FieldFixedLength(5)] public string RcrdId { get; set;  }
        [FieldFixedLength(19)] public string SystemId { get; set;}
        [FieldFixedLength(5)] public string RecordType { get; set;}
        [FieldFixedLength(35)] public string EmployeeCode35 { get; set;}
        [FieldFixedLength(19)] public string DepartmentCode { get; set;}
        [FieldFixedLength(27)] public string Filler { get; set;}

  The variance happens with the RecordType field. Depending what the record type is, the content within EmployeeCode35 will be different; with elements either being blank spaces or containing information, and those varying depending on the type. A substring of (0,14) within EmployeeCode35 may include two data filled fields for one record type, but four for another.

Currently I have all characters of this block stored within EmployeeCode35, and use getters to grab substrings. Only this field differs in the file

As such, I was hoping to subclass for each of the record types processed and split the contents to their respective fields within the subclass using a SplitUpFields() method. Ideally, reducing the need for different parsers which are largely the same apart from this one area.

The issue I have encountered with this is: as the superclass is fixed length record, the subclass must also be fixed length, and I believe it then tries to parse the file based on the [FieldFixedLenth(X)] annotation. And as the file has been fully parsed, it fails.

I was attempting to do this in a way such as:

 
[FixedLengthRecord(FixedMode.ExactLength)]
    public class TestSubClass : FixedLengthRecord
    {
        [FieldFixedLength(15)] public string EmployeeCode15 { get; set; }
        [FieldFixedLength(6)] public string ActionDate { get; set; }
        [FieldFixedLength(6)] public string ActionTime { get; set; }
        [FieldFixedLength(7)] public string StaffId { get; set; }
        [FieldFixedLength(1)] public string Filler { get; set; }
        
        
        public override void SplitUpFields()
        {
            EmployeeCode15 = EmployeeCode35.Substring(0,15);
            ActionDate = EmployeeCode35.Substring(16, 21);
            ActionTime = EmployeeCode35.Substring(22, 27);
            StaffId = EmployeeCode35.Substring(28, 34);
            Filler = EmployeeCode35.Substring(34, 35);
        }

Since the file is fully parsed within the superclass, the subclass throws an exception as it is trying to parse when we have reached end of line. I further tried to leave some of the file to be parsed by the subclass, but the parsing then failed due to there being remaining data not parsed by the superclass.

It is entirely possible this may be something that is not possible, as the documentation did not seem to indicate anything towards doing this. Hoping someone more knowledgable with the library may be able to shed some light.

1

There are 1 best solutions below

0
netniV On

If you want to change the class per row, you should look at Multiple Record Types.

void main() {
    var engine = new MultiRecordEngine(typeof (Orders),
        typeof (Customer),
        typeof (SampleType));

    engine.RecordSelector = new RecordTypeSelector(CustomSelector);

    var res = engine.ReadFile("Input.txt");

   foreach (var rec in res)
       Console.WriteLine(rec.ToString());
}

private Type CustomSelector(MultiRecordEngine engine, string recordLine)
{
    if (recordLine.Length == 0)
        return null;

    if (Char.IsLetter(recordLine[0]))
        return typeof (Customer);
    else if (recordLine.Length == 14)
        return typeof (SampleType);
    else
        return typeof (Orders);
}