0

Using choETL I found that I can map csv position to property name like this

        public class Emp
        {
            public string Name { get; set; }
            public string Other{ get; set; }


            public string MyId { get; set; }
        }

        [Test]
        public void TestMapping()
        {
            ChoCSVRecordConfiguration config = new ChoCSVRecordConfiguration();
            config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("MyId", 1));
            config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Name", 2));
            config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Other", 3));
            config.WithFirstLineHeader(true);

            string csv = @"Id, Name, 
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

            using (var p = ChoCSVReader<Emp>.LoadText(csv, Encoding.ASCII,config)
//                .WithFirstLineHeader(true)
            )
            {
                Console.WriteLine(p.ToList().DumpAsJson());
            }

        }

However what I really want is to be able to map at runtime. Using the following pseudo code:

    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("MyId", "Id"));
    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Name", "Name"));
    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Other", "City"));


    string csv1 = @"Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

    string csv2 = @"Name, Id, City
Tom, 1, NY
Mark, 2, NJ
Lou, 3, FL
Smith, 4, PA
Raj, 5, DC
";

So I can use the same configuration for both csv file. They are almost identical except that the position has been swapped. Is this possible with choETL?

Cinchoo
  • 6,088
  • 2
  • 19
  • 34

1 Answers1

0

UPDATE: This is how you can setup the configuration to meet your requirement

ChoCSVRecordConfiguration config = new ChoCSVRecordConfiguration();
config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("MyId", 0) { FieldName = "Id" });
config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Name", 0) { FieldName = "Name" });
config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Other", 0) { FieldName = "City" });
config.WithFirstLineHeader(false);

Hope this helps.


Yes, it is possible and you started your code correctly. After reviewing your sample code, noticed that you input CSV is missing 3rd field name City. This may be caused the parser to fail.

Here is the working sample.

public class Emp
{
    public string Name { get; set; }
    public string Other { get; set; }


    public string MyId { get; set; }
}

public static void TestMapping()
{
    ChoCSVRecordConfiguration config = new ChoCSVRecordConfiguration();
    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("MyId", 1));
    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Name", 2));
    config.CSVRecordFieldConfigurations.Add(new ChoCSVRecordFieldConfiguration("Other", 3));
    config.WithFirstLineHeader(true);

    string csv = @"Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

    using (var p = ChoCSVReader<Emp>.LoadText(csv, Encoding.ASCII, config))
    {
        Console.WriteLine(p.ToList().Dump());
    }
}

Output:

[Count: 5]
-- CoinCount.Program+Emp State --
        Name: Tom
        Other: NY
        MyId: 1


-- CoinCount.Program+Emp State --
        Name: Mark
        Other: NJ
        MyId: 2


-- CoinCount.Program+Emp State --
        Name: Lou
        Other: FL
        MyId: 3


-- CoinCount.Program+Emp State --
        Name: Smith
        Other: PA
        MyId: 4


-- CoinCount.Program+Emp State --
        Name: Raj
        Other: DC
        MyId: 5

Here is another way, to completely manage the CSV parsing with just with POCO class

[ChoCSVFileHeader(IgnoreHeader = true)]
public class Emp
{
    [ChoCSVRecordField(2)]
    public string Name { get; set; }
    [ChoCSVRecordField(3)]
    public string Other { get; set; }
    [ChoCSVRecordField(1)]
    public string MyId { get; set; }
}

public static void TestMapping()
{
    string csv = @"Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

    using (var p = ChoCSVReader<Emp>.LoadText(csv))
    {
        Console.WriteLine(p.ToList().Dump());
    }
}
Cinchoo
  • 6,088
  • 2
  • 19
  • 34
  • Thank you for your answer and for the code. I must say this is one of the best library that I have used. I love the ease of configuration. I believe that you misunderstood my question hence I'll edit it now to make it easier to understand. – Hoang Tang Mar 31 '20 at 21:04
  • Wow that work! So the trick is to use 0 for the position and WithFirstLineHeader(false). Should we make that position optional or is this such a rare use case that you want to discourage it? – Hoang Tang Mar 31 '20 at 21:47
  • Yes, I'm making this change. Will be available on next release. – Cinchoo Mar 31 '20 at 21:56