FastMember: указанный аргумент находится вне диапазона допустимых значений. Имя параметра: имя

Я пытаюсь использовать CsvHelper для импорта файла CSV и записи его в свою базу данных SQL. Импортируемые данные не принадлежат ни к какому предопределенному классу и должны быть определены во время выполнения. Многие форумы указывали на использование FastMember для этого, но я не смог заставить его работать.

Поскольку у меня нет предопределенного класса, я читаю CSV со следующим кодом:

var records = csv.GetRecords<dynamic>().ToList();

Затем я использую ObjectReader Fastmember для структурирования данных

using (var reader = ObjectReader.Create(data, copyParameters))
{
     await sbc.WriteToServerAsync(reader);
}

На этом этапе я получаю сообщение об ошибке "Указанный аргумент находится вне диапазона допустимых значений. Имя параметра: имя"

Я включу весь фрагмент кода ниже, но copyParameters - это строковый массив, содержащий все столбцы в точности так, как они отображаются в CSV.

Небольшой образец CSV, используемый для тестирования:

DateTime, Column1, Column2, Column3, Column4 08.01.2014 18:20,1,0,0.3,0 1/8/2014 18:21,1,0,0.3,0 1/8/2014 18:22,1,0,0,2,0 1/8/2014 18:23,1,0,0.2,0 1/8/2014 18:24,1,0,0.2,0 08.01.2014 18:25,1,0,0.2,0

Это данные из csv reader и параметры копирования

Вот полный код:

public async Task InsertTimeDataFromImport(IFormFile file, List<ImportCurveGridViewModel> curves, string tableName)
    {
        try
        {
            using (var reader = new StreamReader(file.OpenReadStream()))
            {
                var csv = new CsvReader(reader);
                csv.Configuration.HasHeaderRecord = true;
                csv.Read();

                var records = csv.GetRecords<dynamic>().ToList();

                var copyParameters = curves
                    .Where(c => c.Import)
                    .Select(c => c.CurveName)
                    .ToArray();

                var batchSize = records.Count();

                await _repository.InsertData(tableName, batchSize, records, copyParameters);
            }
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
            throw;
        }

    }

public async Task InsertData(string tableName, int batchSize, IEnumerable<dynamic> data, string[] copyParameters)
    {
        using (SqlBulkCopy sbc = new SqlBulkCopy(_context.Database.GetDbConnection().ConnectionString, SqlBulkCopyOptions.KeepIdentity))
        {
            sbc.DestinationTableName = "[" + tableName + "]";

            sbc.BatchSize = 5000;

            foreach (var param in copyParameters)
            {
                sbc.ColumnMappings.Add(param, param);
            }

            using (var reader = ObjectReader.Create(data, copyParameters))
            {
                await sbc.WriteToServerAsync(reader);
            }
        }
    }

2 ответа

После отсутствия прогресса я решил откусить пулю и перейти на.net core 2.1. Когда я снова получил доступ к DataTable, я смог быстро обойти эту проблему.

В моем случае ошибка была вызвана реализованным оператором [ ] (см. комментарий в коде ниже). После изменения его на методы исключений не было.

      private DataTable TestFastReader()
{
    List<TestClass> data = new List<TestClass>();
    data.Add(new TestClass(1, "Raz"));
    data.Add(new TestClass(2, "Dwa"));
    data.Add(new TestClass(3, "Fszy"));

    DataTable table = new DataTable();

    using (var reader = FastMember.ObjectReader.Create(data))
    {
        table.Load(reader);
    }

    return table;
}

class TestClass
{
    public int Id { get; set; }
    public string Description { get; set; }

    public TestClass(int id, string description)
    {
        this.Id = id;
        this.Description = description;
    }

    // Causes the error in FastMember.ObjectReader
    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }

    public object GetCustomProperty(string propertyName)
    {
        return this.GetType().GetProperty(propertyName).GetValue(this, null);
    }

    public void SetCustomProperty(string propertyName, object val)
    {
        this.GetType().GetProperty(propertyName).SetValue(this, val, null);
    }
}
Другие вопросы по тегам