6

Are there any chances to have the MultiRecordEngine set the line number for each record? I read the documentation and found that the Engine has a LineNumber property, but I couldn't find a way to use it.

What I would like to have: i.e.:

[FixedLengthRecord]
    public class Employee
    {
        public int LineNumber; // <-- setup by the engine while reading the file

        [FieldFixedLength(1)]
        public string Type = "2";

        [FieldFixedLength(6)]
        [FieldTrim(TrimMode.Left, "0")]
        public int ID;
     }

Or... can I rely on the index of the record in the collection created by the Engine.ReadFile? i.e.:

  static void Main(string[] args)
    {

        var engine = new MultiRecordEngine(CustomSelector, _types);
        var obj = engine.ReadFile("order.txt");

        // obj.GetValue(100) returns same record found on the 101th line in the file?
    }
Alexander
  • 558
  • 4
  • 13

1 Answers1

8

You can use the AfterReadRecord event to set the LineNumber property.

Here is a working example

public class Employee
{
    [FieldIgnored]
    public int LineNumber; // <-- setup by the engine while reading the file

    [FieldFixedLength(1)]
    public string Type = "2";

    [FieldFixedLength(6)]
    [FieldTrim(TrimMode.Left, "0")]
    public int ID;
}

class Program
{
    static void Main(string[] args)
    {
        var engine = new FileHelperEngine<Employee>();
        engine.AfterReadRecord += engine_AfterReadRecord;
        Employee[] records = engine.ReadString("2000003" + Environment.NewLine 
                                             + "5000006");

        Employee firstRecord = records[0];
        Assert.AreEqual(1, firstRecord.LineNumber);
        Assert.AreEqual("2", records[0].Type);
        Assert.AreEqual(3, records[0].ID);

        Employee secondRecord = records[1];
        Assert.AreEqual(2, secondRecord.LineNumber);
        Assert.AreEqual("5", records[1].Type);
        Assert.AreEqual(6, records[1].ID);

        Console.Read();
    }

    static void engine_AfterReadRecord(EngineBase engine, AfterReadEventArgs<Employee> e)
    {
        e.Record.LineNumber = engine.LineNumber;
    } 
}
shamp00
  • 11,106
  • 4
  • 38
  • 81
  • 3
    Alternatively you can also have your record class implement `INotifyRead` instead of using the `AfterReadRecord` event. Then all the code is in the FileHelpers class. – shamp00 Jul 02 '14 at 08:21
  • Thanks shamp00! Your alternative is even better! – Alexander Jul 03 '14 at 10:49
  • 1
    Thanks, INotifyRead was exactly what I was searching for :). BTW, FieldIgnored has become "FieldHidden" ! – AFract Sep 18 '18 at 15:26
  • 1
    [FieldIgnored] is now obselete, use [FieldHidden] instead. – nbilal Feb 13 '20 at 08:00