C# CsvHelper:WriteRecord 抛出 "ConfigurationException: Types that inherit IEnumerable cannot be auto mapped"
C# CsvHelper: WriteRecord throws "ConfigurationException: Types that inherit IEnumerable cannot be auto mapped"
这是我的原始代码,不使用 CsvHelper 写入 CSV 文件。
public static void Write(string file, List<PayRecord> payrecords) {
using(StreamWriter sw = new StreamWriter(file)) {
sw.WriteLine("EmployeeId,Gross,Tax,Net");
foreach(PayRecord c in payrecords) {
string line = string.Format("{0},{1},{2},{3}",
c.Id,
c.Gross,
c.Tax,
c.Net);
sw.WriteLine(line);
}
}
}
这是相同的代码,但是这次使用 CsvHelper:
public static void Write(string file, List<PayRecord> payrecords)
{
using (StreamWriter sw = new StreamWriter(file))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
cw.WriteHeader<PayRecord>();
foreach (var c in payrecords)
{
string line = string.Format("{0},{1},{2},{3}",
c.Id,
c.Gross,
c.Tax,
c.Net);
cw.WriteRecord(line);
}
}
}
但我遇到了如下异常:
Unhandled exception. CsvHelper.Configuration.ConfigurationException: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
at CsvHelper.CsvWriter.WriteRecord[T](T record)
和:
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
at CsvHelper.Configuration.ClassMap.AutoMapConstructorParameters(ClassMap map, CsvContext context, LinkedList`1 mapParents, Int32 indexStart)
at CsvHelper.Configuration.ClassMap.AutoMapConstructorParameters(ClassMap map, CsvContext context, LinkedList`1 mapParents, Int32 indexStart)
at CsvHelper.Configuration.ClassMap.AutoMap(CsvContext context)
at CsvHelper.CsvContext.AutoMap(Type type)
at CsvHelper.CsvWriter.WriteHeader(Type type)
at CsvHelper.CsvWriter.WriteHeader[T]()
怎么了?
您正在尝试将 string
写为记录。
cw.WriteRecord(line);
我无法重现您的 ArgumentNullException
但我知道即使修复了该问题,您的代码仍然无法正常工作。
以上将抛出 CsvHelper.Configuration.ConfigurationException
,因为 string
被 class 编辑为单个字段,而 CsvHelper.WriteRecord
更适合 class 而不是string
.
其次,CsvWriter.WriteHeader
不会将“光标”移动到下一行,因此您需要使用 CsvWriter.NextRecord()
否则您的数据将与您的 header 在同一行.
以下代码有效:
public static void Write(string file, List<PayRecord> payrecords) {
using(StreamWriter sw = new StreamWriter(file))
using(CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture)) {
cw.WriteHeader<PayRecord>();
cw.NextRecord();
foreach(var c in payrecords) {
cw.WriteRecord(line);
}
}
}
然而,更好的办法是不要手动编写header,使用CsvHelper.WriteRecords
并传递[=的整个collection 83=] 如下所示。
这会导致正确使用 CsvHelper.WriteRecords
,同时编写正确的 header。
的代码更小、更清晰、更高效
这更好:
public static void Write(string file, List<PayRecord> payrecords)
{
using (StreamWriter sw = new StreamWriter(file))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
cw.WriteRecords(payrecords);
}
}
更好?
要在不阻塞主线程的情况下执行 I/O 操作(写入 CSV 文件),请使用 CsvHelper.WriteRecordsAsync
,使用 await using
不阻塞资源清理并使您的方法 async
才能await
来电。
我还会使用 ICollection<PayRecord>
,这样如果您将 List<PayRecord>
更改为实现 ICollection
的任何其他类型,则无需更改方法。
奶油色:
public static async Task WritePayRecords(string file, ICollection<PayRecord> payrecords)
{
await using (StreamWriter sw = new StreamWriter(file))
await using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
if (payrecords == null)
throw new ArgumentNullException(nameof(payrecords), "Collection of pay records cannot be null");
await cw.WriteRecordsAsync(payrecords);
}
}
上面的代码甚至可以使用 null
字段,null
objects 并且如果 collection 是 null
也会抛出异常(因为否则,CsvHelper 将抛出一个)。
希望对您有所帮助!
这是我的原始代码,不使用 CsvHelper 写入 CSV 文件。
public static void Write(string file, List<PayRecord> payrecords) {
using(StreamWriter sw = new StreamWriter(file)) {
sw.WriteLine("EmployeeId,Gross,Tax,Net");
foreach(PayRecord c in payrecords) {
string line = string.Format("{0},{1},{2},{3}",
c.Id,
c.Gross,
c.Tax,
c.Net);
sw.WriteLine(line);
}
}
}
这是相同的代码,但是这次使用 CsvHelper:
public static void Write(string file, List<PayRecord> payrecords)
{
using (StreamWriter sw = new StreamWriter(file))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
cw.WriteHeader<PayRecord>();
foreach (var c in payrecords)
{
string line = string.Format("{0},{1},{2},{3}",
c.Id,
c.Gross,
c.Tax,
c.Net);
cw.WriteRecord(line);
}
}
}
但我遇到了如下异常:
Unhandled exception. CsvHelper.Configuration.ConfigurationException: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
at CsvHelper.CsvWriter.WriteRecord[T](T record)
和:
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
at CsvHelper.Configuration.ClassMap.AutoMapConstructorParameters(ClassMap map, CsvContext context, LinkedList`1 mapParents, Int32 indexStart)
at CsvHelper.Configuration.ClassMap.AutoMapConstructorParameters(ClassMap map, CsvContext context, LinkedList`1 mapParents, Int32 indexStart)
at CsvHelper.Configuration.ClassMap.AutoMap(CsvContext context)
at CsvHelper.CsvContext.AutoMap(Type type)
at CsvHelper.CsvWriter.WriteHeader(Type type)
at CsvHelper.CsvWriter.WriteHeader[T]()
怎么了?
您正在尝试将 string
写为记录。
cw.WriteRecord(line);
我无法重现您的 ArgumentNullException
但我知道即使修复了该问题,您的代码仍然无法正常工作。
以上将抛出 CsvHelper.Configuration.ConfigurationException
,因为 string
被 class 编辑为单个字段,而 CsvHelper.WriteRecord
更适合 class 而不是string
.
其次,CsvWriter.WriteHeader
不会将“光标”移动到下一行,因此您需要使用 CsvWriter.NextRecord()
否则您的数据将与您的 header 在同一行.
以下代码有效:
public static void Write(string file, List<PayRecord> payrecords) {
using(StreamWriter sw = new StreamWriter(file))
using(CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture)) {
cw.WriteHeader<PayRecord>();
cw.NextRecord();
foreach(var c in payrecords) {
cw.WriteRecord(line);
}
}
}
然而,更好的办法是不要手动编写header,使用CsvHelper.WriteRecords
并传递[=的整个collection 83=] 如下所示。
这会导致正确使用 CsvHelper.WriteRecords
,同时编写正确的 header。
这更好:
public static void Write(string file, List<PayRecord> payrecords)
{
using (StreamWriter sw = new StreamWriter(file))
using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
cw.WriteRecords(payrecords);
}
}
更好?
要在不阻塞主线程的情况下执行 I/O 操作(写入 CSV 文件),请使用 CsvHelper.WriteRecordsAsync
,使用 await using
不阻塞资源清理并使您的方法 async
才能await
来电。
我还会使用 ICollection<PayRecord>
,这样如果您将 List<PayRecord>
更改为实现 ICollection
的任何其他类型,则无需更改方法。
奶油色:
public static async Task WritePayRecords(string file, ICollection<PayRecord> payrecords)
{
await using (StreamWriter sw = new StreamWriter(file))
await using (CsvWriter cw = new CsvWriter(sw, CultureInfo.CurrentCulture))
{
if (payrecords == null)
throw new ArgumentNullException(nameof(payrecords), "Collection of pay records cannot be null");
await cw.WriteRecordsAsync(payrecords);
}
}
上面的代码甚至可以使用 null
字段,null
objects 并且如果 collection 是 null
也会抛出异常(因为否则,CsvHelper 将抛出一个)。
希望对您有所帮助!