Как заставить FileHelpers устанавливать номер строки для каждой записи?

#c#-4.0 #filehelpers

#c #-4.0 #filehelpers

Вопрос:

Есть ли шансы, что MultiRecordEngine установит номер строки для каждой записи? Я прочитал документацию и обнаружил, что движок имеет свойство lineNumber, но я не смог найти способ его использовать.

Что я хотел бы иметь: т.е.:

 [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;
     }
  

Или … я могу полагаться на индекс записи в коллекции, созданной движком.ReadFile?
т.е.:

   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?
    }
  

Ответ №1:

Вы можете использовать AfterReadRecord событие для установки свойства lineNumber .

Вот рабочий пример

 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;
    } 
}
  

Комментарии:

1. В качестве альтернативы вы также можете реализовать свой класс записи INotifyRead<Employee> вместо использования AfterReadRecord события. Тогда весь код находится в классе FileHelpers .

2. Спасибо shamp00! Ваша альтернатива еще лучше!

3. Спасибо, INotifyRead — это именно то, что я искал :). Кстати, FieldIgnored стал «FieldHidden»!

4. [FieldIgnored] теперь удален, вместо этого используйте [FieldHidden] .