Search code examples
c#etlfilehelpersrhino-etl

How can I separate rows with different RowTypes using FileHelpers?


For example, I have the next file test.txt with two Rows:

Type00007P 008 PPL

Type00230J 190 1

And the next classes in my code to use the Rhino-ETL Nuget to insert those rows on my DB:

public class Type00007P
{
    [FieldFixedLength(10)]
    [FieldTrim(TrimMode.Both)]
    public string TypeControl;

    [FieldFixedLength(3)]
    [FieldTrim(TrimMode.Both)]
    public int Id;

    [FieldFixedLength(3)]
    [FieldTrim(TrimMode.Both)]
    public string Name;
}


public class Type00230J
{
    [FieldFixedLength(10)]
    [FieldTrim(TrimMode.Both)]
    public string TypeControl;

    [FieldFixedLength(3)]
    [FieldTrim(TrimMode.Both)]
    public int Id;

    [FieldFixedLength(1)]
    [FieldTrim(TrimMode.Both)]
    public bool Calculated;
}

If I use the next code to extract the Rows, I cannot differentiate between rows Type00007P and rows Type00230J in the same file:

public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
    using (FileEngine file = FluentFile.For<Type00007P>().From(FilePath))
    {
        foreach (object obj in file)
        {
            yield return Row.FromObject(obj);
        }
    }
}

Then, how can I read the first fixed field to get the RowType and after that, process that whole line with the correct class?

Regards!


Solution

  • You can use the MultiRecordEngine. Documentation is here.

    var engine = new MultiRecordEngine(
        typeof(Type00007P),
        typeof(Type00230J));
    
    engine.RecordSelector = new RecordTypeSelector(CustomSelector);
    

    and then define a CustomSelector.

    private Type CustomSelector(MultiRecordEngine engine, string recordLine)
    {
        if (recordLine.Length == 0)
            return null;
    
        if (recordLine.StartsWith("Type00007P")))
            return typeof(Type00007P);
        else
            return typeof(Type00230J);
    }