Как обрезать все значения столбцов с помощью CsvEngine.CsvToDataTable ()? - PullRequest
0 голосов
/ 26 ноября 2018

Я использую FileHelpers 3.3.1 для импорта данных CSV и заполнения DataTables в моем приложении c #.Это работает хорошо, и вот как я это называю:

DataTable dt = CsvEngine.CsvToDataTable(fullPath, ',');

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

Есть ли способ вызвать "автоматически обрезать все значения столбцов "во время вызова CsvToDataTable()?

Я знаю, что есть атрибут FieldTrim , который делает именно это, но я не могу привязать жесткие классы к моим файлам CSV, потому чтоУ меня есть много разных файлов CSV, и у всех них разные имена столбцов и типы данных.Так что это не практичный вариант для меня.Кажется, что есть встроенный способ trim с использованием одного из универсальных парсеров CSV, таких как CsvToDataTable().

Какой мой лучший вариант?

1 Ответ

0 голосов
/ 29 ноября 2018

Класс FileHelpers CsvEngine довольно ограничен.Это класс sealed, поэтому вы не можете легко наследовать или переопределять его.

Если вы не возражаете против хакерского решения, работает следующее

// Set the internal TrimChars via reflection
public static class FileBaseExtensions
{
    public static void SetTrimCharsViaReflection(this FieldBase field, Char [] value)
    {
        var prop = typeof(FieldBase).GetProperty("TrimChars", BindingFlags.NonPublic | BindingFlags.Instance);
        prop.SetValue(field, value);
    }
}

CsvOptions options = new CsvOptions("Records", ',', filename);
var engine = new CsvEngine(options);            
foreach (var field in engine.Options.Fields)
{
    field.SetTrimCharsViaReflection(new char[] { ' ', '\t' });
    field.TrimMode = TrimMode.Both;
}
var dataTable = engine.ReadFileAsDT(filename);

Но вам лучше использовать стандартный FileHelperEngine и создать собственную версию CsvClassBuilder (исходный код здесь ) для создания класса отображения.Вам необходимо изменить метод AddFields следующим образом:

public override DelimitedFieldBuilder AddField(string fieldName, string fieldType)
{
    base.AddField(fieldName, fieldType);
    if (base.mFields.Count > 1)
    {
        base.LastField.FieldOptional = true;
        base.LastField.FieldQuoted = true;
        base.LastField.QuoteMode = QuoteMode.OptionalForBoth;
        base.LastField.QuoteMultiline = MultilineMode.AllowForBoth;

        // <New>
        base.LastField.TrimMode = TrimMode.Both;
        base.LastField.TrimChars = " \t"; // trim spaces and tabs
        // </New>
    }
    return base.LastField;
} 

При необходимости вы можете поднять код для CsvToDataTable из исходного кода для CsvEngine, который здесь .

...