I am attempting to use CsvHelper to improve my manual conversion process from objects to csv records/rows. I have created a complex ClassMap
that I wanted to use to write a list of objects out to a file. How can I add the ClassMap
to the CsvHelper instance's Configuration for writing?
I am getting the following exception and message now:
public class SpecimenMap : ClassMap<Specimen>
{
public SpecimenMap()
{
Map(s =>
DataFunctions.GetSiteByName(s.SiteName).RecordNo.ToString() + "-" +
s.SpecimenNumber.ToString()).
Index(0).Name("recordNumber");
Map(s =>
s.RecordNo.ToString()).
Index(1).Name("specimenNumber");
/* many more, but I set a breakpoint on the first 'Map' and it throws the exception. I also tried commenting out the first 'Map' and running the second (since the first includes calls to external functions), it had identical results. */ ....
using (var writer = new StreamWriter(localFileLocation))
using (var csv = new CsvWriter(writer))
{
csv.Configuration.RegisterClassMap<SpecimenMap>(); // this line throws exception
csv.WriteRecords(specimen);
}
Exception Thrown:
System.InvalidOperationException: No members were found in expression '{expression}'.
In my research I found this code but I don't know how to interpret the exception. Something about the Stack size after doing some kind of Reflection (Line 34). https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/Configuration/ClassMap%601.cs
The error you are getting is telling you that the Map()
function expects to only get a class member from it's expression. Map(s => s.SiteName)
. If you want to further manipulate the output, you can use ConvertUsing()
.
Updated for Version 27.2.1. ClassMap
is registered on the Context
and ConvertUsing()
has been changed to Convert()
.
public static void Main(string[] args)
{
using (var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
{
var specimen = new List<Specimen> { new Specimen { SiteName = "DeepThought", SpecimenNumber = 1 } };
csv.Context.RegisterClassMap<SpecimenMap>();
csv.WriteRecords(specimen);
Console.Read();
}
}
public class SpecimenMap : ClassMap<Specimen>
{
public SpecimenMap()
{
Map(s => s.SiteName).Index(0).Name("recordNumber").Convert(s => GetSiteByName(s.Value.SiteName) + "-" + s.Value.SpecimenNumber);
Map(s => s.SpecimenNumber).Index(1).Name("specimenNumber");
}
}
public class Specimen
{
public string SiteName { get; set; }
public int SpecimenNumber { get; set; }
}
public static int GetSiteByName(string siteName)
{
if (siteName == "DeepThought")
{
return 42;
}
return 1;
}
Original
public static void Main(string[] args)
{
using (var csv = new CsvWriter(Console.Out))
{
var specimen = new List<Specimen> { new Specimen { SiteName = "DeepThought", SpecimenNumber = 1 } };
csv.Configuration.RegisterClassMap<SpecimenMap>();
csv.WriteRecords(specimen);
Console.ReadKey();
}
}
public class SpecimenMap : ClassMap<Specimen>
{
public SpecimenMap()
{
Map(s => s.SiteName).Index(0).Name("recordNumber").ConvertUsing(s => GetSiteByName(s.SiteName) + "-" + s.SpecimenNumber);
Map(s => s.SpecimenNumber).Index(1).Name("specimenNumber");
}
}
public class Specimen
{
public string SiteName { get; set; }
public int SpecimenNumber { get; set; }
}
public static int GetSiteByName(string siteName)
{
if (siteName == "DeepThought")
{
return 42;
}
return 1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With