CsvHelper 和 IEnumerable<object> 将多条记录写入 CSV 文件的问题

问题描述

我正在尝试使用 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 answerWriting only selected columns to CSV-file using CsvHelper

,

虽然不是答案,但我无法实现我所需要的,所以我改用了 DataTable。