问题描述
我正在尝试使用 CsvHelper 使用 IEnumerable<object>
创建一个包含多行的 CSV 文件。当我将数据传递给创建 CSV 文件的函数并且 IEnumerable<object>
的计数大于 1 时,它会引发错误:
继承 IEnumerable 的类型无法自动映射。你是否 不小心调用了作用于单个的 GetRecord 或 WriteRecord 记录而不是调用 GetRecords 或 WriteRecords 作用于 记录列表?
当只有一个元素时,CsvWriter 可以完美运行,但是,有时 IEnumerable<object>
中最多可以包含 96 个以上的项目,并且需要将它们放入一个文件中。期望的结果是可以将 IEnumerable<object>
的内容写入 CSV 文件,最好使用 CsvHelper。
public void SaveCsvData(IEnumerable<object> csvDataToWritetoFile,string path)
{
CsvConfiguration csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = false
};
using (StreamWriter streamWriter = new StreamWriter(path,false))
using (CsvWriter csvWriter = new CsvWriter(streamWriter,csvConfig))
{
csvWriter.WriteRecords(csvDataToWritetoFile);
}
}
foreach (var item in csvDataToWritetoFile.ToList())
{
csvWriter.WriteRecords(csvDataToWritetoFile);
}
还有...
foreach (var item in csvDataToWritetoFile.ToList())
{
csvWriter.WriteRecord(item);
}
谁能建议我如何补救将多个项目从一个对象写入一个文件的能力,因为我不知道该怎么做?
我没有映射类的原因是我有一个非常非常大的枢轴,它具有多种类型的时间分辨率,并且枢轴本质上必须是动态的。
这是枢轴:
public static IEnumerable<object> PivotH(List<CsvModel> csvData)
{
csvData.ForEach(x =>
{
x.ReadingDate = csvData.Select(x => x.ReadingDate).Min();
});
List<CsvModel> data = (from x in csvData
group x by new
{
x.Meter_Identifier,x.Units,x.ReadingDate
}
into grp
select new CsvModel
{
Meter_Identifier = grp.Key.Meter_Identifier,Units = grp.Key.Units,ReadingDate = grp.Key.ReadingDate,#region Pivot
r1 = grp.Where(i => i.ReadingTime.ToString() == "01:00").Select(x => x.ReadingValue).FirstOrDefault(),r2 = grp.Where(i => i.ReadingTime.ToString() == "02:00").Select(x => x.ReadingValue).FirstOrDefault(),r3 = grp.Where(i => i.ReadingTime.ToString() == "03:00").Select(x => x.ReadingValue).FirstOrDefault(),r4 = grp.Where(i => i.ReadingTime.ToString() == "04:00").Select(x => x.ReadingValue).FirstOrDefault(),r5 = grp.Where(i => i.ReadingTime.ToString() == "05:00").Select(x => x.ReadingValue).FirstOrDefault(),r6 = grp.Where(i => i.ReadingTime.ToString() == "06:00").Select(x => x.ReadingValue).FirstOrDefault(),r7 = grp.Where(i => i.ReadingTime.ToString() == "07:00").Select(x => x.ReadingValue).FirstOrDefault(),r8 = grp.Where(i => i.ReadingTime.ToString() == "08:00").Select(x => x.ReadingValue).FirstOrDefault(),r9 = grp.Where(i => i.ReadingTime.ToString() == "09:00").Select(x => x.ReadingValue).FirstOrDefault(),r10 = grp.Where(i => i.ReadingTime.ToString() == "10:00").Select(x => x.ReadingValue).FirstOrDefault(),r11 = grp.Where(i => i.ReadingTime.ToString() == "11:00").Select(x => x.ReadingValue).FirstOrDefault(),r12 = grp.Where(i => i.ReadingTime.ToString() == "12:00").Select(x => x.ReadingValue).FirstOrDefault(),r13 = grp.Where(i => i.ReadingTime.ToString() == "13:00").Select(x => x.ReadingValue).FirstOrDefault(),r14 = grp.Where(i => i.ReadingTime.ToString() == "14:00").Select(x => x.ReadingValue).FirstOrDefault(),r15 = grp.Where(i => i.ReadingTime.ToString() == "15:00").Select(x => x.ReadingValue).FirstOrDefault(),r16 = grp.Where(i => i.ReadingTime.ToString() == "16:00").Select(x => x.ReadingValue).FirstOrDefault(),r17 = grp.Where(i => i.ReadingTime.ToString() == "17:00").Select(x => x.ReadingValue).FirstOrDefault(),r18 = grp.Where(i => i.ReadingTime.ToString() == "18:00").Select(x => x.ReadingValue).FirstOrDefault(),r19 = grp.Where(i => i.ReadingTime.ToString() == "19:00").Select(x => x.ReadingValue).FirstOrDefault(),r20 = grp.Where(i => i.ReadingTime.ToString() == "20:00").Select(x => x.ReadingValue).FirstOrDefault(),r21 = grp.Where(i => i.ReadingTime.ToString() == "21:00").Select(x => x.ReadingValue).FirstOrDefault(),r22 = grp.Where(i => i.ReadingTime.ToString() == "22:00").Select(x => x.ReadingValue).FirstOrDefault(),r23 = grp.Where(i => i.ReadingTime.ToString() == "23:00").Select(x => x.ReadingValue).FirstOrDefault(),r24 = grp.Where(i => i.ReadingTime.ToString() == "00:00").Select(x => x.ReadingValue).FirstOrDefault()
#endregion
}).ToList();
var returnData = (from x in data
select new
{
Meter_Identifier = x.Meter_Identifier,Units = x.Units,ReadingDate = x.ReadingDate,r1 = x.r1,r2 = x.r2,r3 = x.r3,r4 = x.r4,r5 = x.r5,r6 = x.r6,r7 = x.r7,r8 = x.r8,r9 = x.r9,r10 = x.r10,r11 = x.r11,r12 = x.r12,r13 = x.r13,r14 = x.r14,r15 = x.r15,r16 = x.r16,r17 = x.r17,r18 = x.r18,r19 = x.r19,r20 = x.r20,r21 = x.r21,r22 = x.r22,r23 = x.r23,r24 = x.r24
}).ToList();
return returnData;
}
这是小支点。 CsvModel 有 1440 多个属性,用于 24 小时内以分钟为单位的不同时间分辨率。然后,我根据所选的分辨率对数据进行分组,在上面的示例中,这是一小时的时间段。
TIA
解决方法
与其返回 CsvModel
对象的一个子集并尝试将其写出,您可以做的是返回整个对象并为每个枢轴创建一个 ClassMap
。您可以指定要在每个地图中输出的字段。
public void SaveCsvData(IEnumerable<CsvModel> csvDataToWriteToFile,string path,ClassMap<CsvModel> map)
{
CsvConfiguration csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = false
};
using (StreamWriter streamWriter = new StreamWriter(path,false))
using (CsvWriter csvWriter = new CsvWriter(streamWriter,csvConfig))
{
csvWriter.Context.RegisterClassMap(map);
csvWriter.WriteRecords(csvDataToWriteToFile);
}
}
参见 CsvHelper 的示例 here
改编自this answer到Writing only selected columns to CSV-file using CsvHelper
,虽然不是答案,但我无法实现我所需要的,所以我改用了 DataTable。