Добавить фиктивные пустые поля в CSVHelper

Я использую библиотеку CsvHelper для написания CSV. У меня есть объект, который не содержит всех записей, и мне нужно добавить пустые поля в свой CSV. Например:

public class Example
{
   public string Test1 { get; set; }
   public string Test2 { get; set; }
}

с этой картой:

public class ExampleMap : ClassMap<Example>
{
    public ExampleMap()
    {
      Map(ex=>ex.Test1).Index(0);
      Map(ex=>ex.Test2).Index(4);
    }
}

и я хотел бы иметь для этого объекта

new Example() { Test1="dummy", Test2="field" };

этот результат csv:

dummy;;;field

Я очень борюсь с этой проблемой, если кто-то может мне помочь :) Большое спасибо


person Creep    schedule 11.09.2014    source источник


Ответы (3)


Примечание. В более новых версиях он может быть заменен оператором Constant().

Более согласованный с API подход может заключаться в использовании пользовательского ITypeConverter. Вот как я его использую:

Map(i => i.SomeUnusedId).Name("SomeId").TypeConverter<EmptyConverter>(); //converst to an empty string

Тогда конвертер может выглядеть так:

public class EmptyConverter : ITypeConverter {
    /// <inheritdoc />
    public bool CanConvertFrom(Type type) {
        return true;
    }

    /// <inheritdoc />
    public bool CanConvertTo(Type type) {
        return true;
    }

    /// <inheritdoc />
    public object ConvertFromString(TypeConverterOptions options, string text) {
        return string.Empty;
    }

    /// <inheritdoc />
    public string ConvertToString(TypeConverterOptions options, object value) {
        return string.Empty;
    }
}
person Marcel    schedule 10.06.2020

Похоже, концепция явного сопоставления столбцов между ними нарушена.

Кажется, что библиотека CsvHelper не поддерживает такие сценарии, потому что библиотека просто использует индексы в порядке возрастания для сопоставления определенных столбцов («сопоставленных столбцов»).

Но, если такой вывод действительно необходим, «неиспользуемые» (зарезервированные) столбцы можно ввести следующим образом:

internal sealed class Example
{
    public string Test1 { get; set; }
    public string Test2 { get; set; }

    public string Reserved1 { get; set; }
    public string Reserved2 { get; set; }
}

internal sealed class ExampleMap : CsvClassMap<Example>
{
    public ExampleMap()
    {
        Map(ex => ex.Test1).Index(0);
        Map(ex => ex.Reserved1).Index(1);
        Map(ex => ex.Reserved2).Index(2);
        Map(ex => ex.Test2).Index(3);
    }
}
person Sergey Vyacheslavovich Brunov    schedule 11.09.2014
comment
Это будет огромная трата времени для моего случая (у меня было около 100 пустых полей в одном из моих CSV) (я переписываю старый EDI, который управляется с пустым полем ...!) И я пробовал много (глупых) вещей (добавление фиктивного PropertyInfo в PropertyMap, зарегистрируйте такое же фиктивное свойство ...). Я подумываю отредактировать ядро ​​csvhelper, чтобы решить мою проблему! (Я заглянул в ваш блог, это приятно!) - person Creep; 12.09.2014
comment
Есть ли имена полей в начале CSV-файла? - person Sergey Vyacheslavovich Brunov; 12.09.2014
comment
Без заголовка, только данные! - person Creep; 12.09.2014
comment
Это интересно. Требуется более подробная информация о том, что такое структура входных данных (предполагается, что это не два свойства?) И как должен выглядеть CSV-файл (ближе к реальному миру). P.S. Спасибо! Рад, что вам понравился блог. знак равно - person Sergey Vyacheslavovich Brunov; 12.09.2014
comment
Структура реального мира - это смешанные данные (дата, серийные номера, закодированный статус и т. Д., И есть много потоков (10 файлов с 5-50 свойствами, сопоставленными с базой данных на нашей стороне и с чем угодно на стороне нашего партнера), я написал множество конвертеров, которые плохо управлялись в старом приложении и выглядят более хорошо управляемыми с помощью структуры csvhelper, за исключением пустых полей (извините за мой английский, это не мой родной язык!) - person Creep; 12.09.2014
comment
Не могли бы вы пояснить, какая высокоуровневая проблема решается? Экспорт таблицы с сервера SQL в файл CSV? - person Sergey Vyacheslavovich Brunov; 12.09.2014
comment
Да, данные поступают в основном из базы данных, но они сформированы так, чтобы соответствовать старому EDI с партнером. Другая часть поступает из нашей ERP, а другая - из файловой системы. Я смотрел пакеты SSIS, но наш обмен сложен и состоит из двух частей: FTP-депозита и так далее ...! - person Creep; 12.09.2014
comment
В общем, я хотел бы порекомендовать вам сгенерировать классы сопоставления строк и строк из существующих таблиц SQL (каким-то образом), а затем использовать CsvHelper библиотеку с этими классами сопоставления строк и строк. Что вы думаете? - person Sergey Vyacheslavovich Brunov; 12.09.2014
comment
Это не решит мою проблему с пустым полем. Все сопоставление уже выполнено (все сделано, кроме решения этой проблемы), и индекс хорош, но я не могу понять, как решить эту проблему! :( - person Creep; 12.09.2014
comment
Это решит проблему, если в сгенерированных строках и сопоставлениях строк есть зарезервированные поля. - person Sergey Vyacheslavovich Brunov; 12.09.2014
comment
Не знаю, может ли это быть полезным, но вы можете попробовать использовать методы CsvWriter.WriteField() и CsvWriter.NextRecord() вместо использования строк и сопоставлений строк. Это своего рода низкоуровневый API. - person Sergey Vyacheslavovich Brunov; 12.09.2014

Наконец, я решил напрямую редактировать окончательную строку csv для каждой строки ... Это работает, но уродливо!

person Creep    schedule 11.09.2014