Csvhelper: How to manage missing fields on Auto Mapping

Created on 19 Mar 2019  ·  5Comments  ·  Source: JoshClose/CsvHelper

Cvs File:

filedA,fieldB,fieldC

1,"a",3

ClassA
{
Type fieldA;
string jsonvalues;
}

In my code,
ClassA a=GetRecord()
i want following result:
a.fieldA=1
a.jsonvalues={"fieldB":"a","fieldC":"3"}

How to do?

All 5 comments

A TypeConverter won't work here as those run agains each value. You could do this in the model:

ClassA {
Type FieldA;
string FieldB;
string FieldC;
[Ignore]
string jsonvalues { get => new { fieldB = FieldB, fieldC = FieldC }; };
}

basically importing each as a column but then have a getter to combine them.

basically importing each as a column but then have a getter to combine them.

thank you. that is a direct solution ,not automatic mapping。
for example,
Cvs File A:
filedA,fieldB,fieldC
1,"a",3
Cvs File B:
filedA,fieldB,fieldD,FieldE
2,"a",2019/02/01,"tom"
ClassA
{
Type fieldA;
string jsonvalues;
}

In my code,
ClassA a=GetRecord() // from Cvs File A
ClassA b=GetRecord()// from Cvs File B
i want following result:
a.fieldA=1
a.jsonvalues={"fieldB":"a","fieldC":"3"}
b.fieldA=2
b.jsonvalues={"fieldB":"a","fieldD":"2019/02/01","FieldE":"tom"}

How to do?

void Main()
{
    var s = new StringBuilder();
    s.AppendLine("FieldA,FieldB,FieldC");
    s.AppendLine("1,\"a\",3");
    using (var reader = new StringReader(s.ToString()))
    using (var csv = new CsvReader(reader))
    {       
        csv.Configuration.RegisterClassMap<ClassAMap>();
        csv.Configuration.RegisterClassMap<JsonDataMap>();
        csv.GetRecords<ClassA>().ToList().Dump();
    }
}

public class ClassA
{
    public int FieldA { get; set; }
    public string Json { get; set; }
}

public class ClassAMap : ClassMap<ClassA>
{
    public ClassAMap()
    {
        Map(m => m.FieldA);
        Map(m => m.Json).ConvertUsing(row =>
        {
            var jsonData = row.GetRecord<JsonData>();
            return JsonConvert.SerializeObject(jsonData);
        });
    }
}

public class JsonData
{
    public string FieldB { get; set; }
    public int FieldC { get; set; }
}

public class JsonDataMap : ClassMap<JsonData>
{
    public JsonDataMap()
    {
        Map(m => m.FieldB);
        Map(m => m.FieldC);
    }
}

Thank you!JoshClose, pynej.
The following algorithm is what I want.

static void Main(string[] args)
{
    var s = new StringBuilder();
    s.AppendLine("FieldA,FieldB,FieldC");
    s.AppendLine("1,\"a\",3");
    using (var reader = new StringReader(s.ToString()))
    using (var csv = new CsvReader(reader))
    {
          csv.Configuration.RegisterClassMap<ClassAMap>();
          csv.GetRecords<ClassA>().ToList();
    }
}

public class ClassA
{
    public int FieldA { get; set; }
    public string Json { get; set; }
}

public class ClassAMap : ClassMap<ClassA>
{
     public ClassAMap()
     {
          Map(m => m.FieldA);
          Map(m => m.Json).ConvertUsing(row =>
          {
                Dictionary<string, string> records =  new Dictionary<string, string>();
                List<string> fieldHeaderList = new List<string>(row.Context.HeaderRecord);
                fieldHeaderList.Remove("FieldA");
                foreach (string field in fieldHeaderList)
                {
                    records.Add(field, row.GetField(field));
                }
                return JsonConvert.SerializeObject(records);
          });
     }
} 
Was this page helpful?
0 / 5 - 0 ratings