Suppose I have data structures like this:
public class Foo
{
public Bar A {get;set;}
public Bar B {get;set;}
public int C {get;set;}
}
public class Bar
{
public int Value {get;set;}
}
and a CSV file with the contents
Column1,Column2,Column3
0,1,2
3,4,5
I would like to now map Column1
to A.Value
and Column2
to B.Value
and Column3
to C
.
I'm restricted to runtime mapping.
For Column3
-> C
, I can write
var type = typeof(Foo);
var customMap = Activator.CreateInstance(typeof(DefaultClassMap<>).MakeGenericType(type)) as ClassMap;
customMap.Map(type, type.GetProperty("C")).Name("Column3");
csv_reader.Context.RegisterClassMap(customMap);
How can I map columns 1 and 2?
Currently you can do this.
void Main()
{
var s = new StringBuilder();
s.Append("Column1,Column2,Column3\r\n");
s.Append("0,1,2\r\n");
s.Append("3,4,5\r\n");
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
};
using (var reader = new StringReader(s.ToString()))
using (var csv = new CsvReader(reader, config))
{
var fooType = typeof(Foo);
var barType = typeof(Bar);
var fooMapType = typeof(DefaultClassMap<>).MakeGenericType(fooType);
var barMapType = typeof(DefaultClassMap<>).MakeGenericType(barType);
var map = (ClassMap)ObjectResolver.Current.Resolve(fooMapType);
map.Map(fooType, fooType.GetProperty("C")).Name("Column3");
map.References(barMapType, fooType.GetProperty("A")).Data.Mapping.Map(barType, barType.GetProperty("Value")).Name("Column1");
map.References(barMapType, fooType.GetProperty("B")).Data.Mapping.Map(barType, barType.GetProperty("Value")).Name("Column2");
csv.Context.RegisterClassMap(map);
csv.GetRecords<Foo>().ToList().Dump();
}
}
private class Foo
{
public Bar A { get; set; }
public Bar B { get; set; }
public int C { get; set; }
}
public class Bar
{
public int Value { get; set; }
}
I'm looking into ways to make this easier for people that want to create maps at runtime.