How to make FileHelpers set the line number on each record?
Asked Answered
G

1

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?
    }
Gal answered 30/6, 2014 at 14:2 Comment(0)
S
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;
    } 
}
Surplusage answered 2/7, 2014 at 8:9 Comment(4)
Alternatively you can also have your record class implement INotifyRead<Employee> instead of using the AfterReadRecord event. Then all the code is in the FileHelpers class.Surplusage
Thanks shamp00! Your alternative is even better!Gal
Thanks, INotifyRead was exactly what I was searching for :). BTW, FieldIgnored has become "FieldHidden" !Selry
[FieldIgnored] is now obselete, use [FieldHidden] instead.Bankston

© 2022 - 2024 — McMap. All rights reserved.