Как записать только выбранные поля класса в CSV с помощью CsvHelper?

я использую CsvHelper читать и писать CSV-файлы, и это здорово, но я не понимаю, как писать только выбранные поля типа.

мы:

using CsvHelper.Configuration;

namespace Project
{
    public class DataView
    {
        [CsvField(Name = "N")]
        public string ElementId { get; private set; }

        [CsvField(Name = "Quantity")]
        public double ResultQuantity { get; private set; }

        public DataView(string id, double result)
        {
            ElementId = id;
            ResultQuantity = result;
        }
    }
}

и мы хотели исключить слова "количество" CsvField из результирующего CSV-файла, который мы в настоящее время генерируем через что-то вроде:

using (var myStream = saveFileDialog1.OpenFile())
{
    using (var writer = new CsvWriter(new StreamWriter(myStream)))
    {
        writer.Configuration.Delimiter = 't';
        writer.WriteHeader(typeof(ResultView));
        _researchResults.ForEach(writer.WriteRecord);
    }
}

что я могу использовать для динамического исключения поля типа из CSV?

если это необходимо, мы могли бы обработать полученный файл, но я делаю не знаю как удалить весь столбец CSV с CsvHelper.

3 ответов


вы можете сделать это:

using (var myStream = saveFileDialog1.OpenFile())
{
    using (var writer = new CsvWriter(new StreamWriter(myStream)))
    {
        writer.Configuration.AttributeMapping(typeof(DataView)); // Creates the CSV property mapping
        writer.Configuration.Properties.RemoveAt(1); // Removes the property at the position 1
        writer.Configuration.Delimiter = "\t";
        writer.WriteHeader(typeof(DataView));
        _researchResults.ForEach(writer.WriteRecord);
    }
}

мы заставляем создание сопоставления атрибутов, а затем модифицируем его, динамически удаляя столбец.


недавно мне нужно было достичь аналогичного результата, определив, какие поля включать во время выполнения. Таков был мой подход:--3-->

  1. создайте файл сопоставления для сопоставления полей, которые мне нужны во время выполнения, передав перечисление в конструктор класса

    public sealed class MyClassMap : CsvClassMap<MyClass>
    {
        public MyClassMap(ClassType type)
        {
            switch (type)
            {
                case ClassType.TypeOdd
                    Map(m => m.Field1);
                    Map(m => m.Field3);
                    Map(m => m.Field5);                 
                    break;
                case ClassType.TypeEven:
                    Map(m => m.Field2);
                    Map(m => m.Field4);
                    Map(m => m.Field6);                 
                    break;
                case ClassType.TypeAll:
                    Map(m => m.Field1);
                    Map(m => m.Field2);
                    Map(m => m.Field3);
                    Map(m => m.Field4);
                    Map(m => m.Field5);
                    Map(m => m.Field6);                 
                    break;
            }
        }
    }
    
  2. выпишите записи с помощью конфигурации сопоставления

    using (var memoryStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memoryStream))
    using (var csvWriter = new CsvWriter(streamWriter))
    {
        csvWriter.Configuration.RegisterClassMap(new MyClassMap(ClassType.TypeOdd));
        csvWriter.WriteRecords(records);
        streamWriter.Flush();
        return memoryStream.ToArray();
    }
    

отметьте поле следующим образом:

[CsvField( Ignore = true )]
public double ResultQuantity { get; private set; }

обновление: Фигу. Я вижу, вы хотите сделать это во время выполнения, а не компиляции. Я оставлю это как красный флаг для всех, кто может совершить ту же ошибку.