При попытке использовать ExcelDataReader для загрузки файла в базу данных появляется ошибка «Указанный метод не поддерживается» - PullRequest
0 голосов
/ 17 февраля 2020

Я написал метод BulkCopy для загрузки файла Excel в SQL Таблица базы данных сервера. Я пытаюсь выполнить модульное тестирование, и каждый раз происходит сбой с «System.NotSupportedException: указанный метод не поддерживается».

Если бы кто-то мог взглянуть, он был бы очень признателен.

С уважением,

Эммет

    public static void BulkCopy(string inputFilePath, string tableName)
    {

        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {

                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column = cols.GetValue(0).ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 3");
                    }

                //continued for column mappings...

                }

                bulkCopy.WriteToServer(reader);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
        }
    }

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Я проверил ваш код, проблема показана в следующем коде, ваш читатель неверен.

bulkCopy.WriteToServer(reader);

Передайте данные в массив , попробуйте следующий код

public static void BulkCopy(string inputFilePath, string tableName)
    {
        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = System.IO.File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        IExcelDataReader reader;

        if (inputFilePath.EndsWith(".xls"))
            reader = ExcelReaderFactory.CreateBinaryReader(stream);
        else if (inputFilePath.EndsWith(".xlsx"))
            reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        else
            throw new Exception("The file to be processed is not an Excel file");
        var conf = new ExcelDataSetConfiguration
        {
            ConfigureDataTable = _ => new ExcelDataTableConfiguration
            {
                UseHeaderRow = true
            }
        };
        var dataSet = reader.AsDataSet(conf);

        // Now you can get data from each sheet by its index or its "name"
        var dataTable = dataSet.Tables[0];

        using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {
                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column =col.ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column3");
                    }

                    //continued for column mappings...

                }
                bulkCopy.WriteToServer(dataTable);
            }
            Console.WriteLine("Copy data to database done (DataReader).");           
    }

Передайте DataReader в объем , измените свою foreach деталь, как показано

               for (var i = 0; i<cols.Count();i++)
                {
                    if (cols[i].ToString().Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column1");
                    }

                    if (cols[i].ToString().Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column2");
                    }

                    if (cols[i].ToString().Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column3");
                    }

                    //continued for column mappings...

                }
0 голосов
/ 18 февраля 2020

Вам нужно изменить способ установки сопоставления столбцов. Если вы удалите их, это будет работать. В приведенном вами примере ссылка они используют GetName для получения столбцов. Я попробовал это, и это почему-то не работает. Я получаю GetOrdinal ошибку. Это та же самая ошибка, которая исходит из вашего кода: ExcelDataReader.ExcelDataReader`2.GetOrdinal(String name).

Не знаю, насколько она хороша, но она работает.

public static void BulkCopy(string inputFilePath, string tableName)
    {

        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {

                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                     if (cols[i].ToString() == "Column 1")
                     {
                          bulkCopy.ColumnMappings.Add(i, "Column 1");
                     }

                     if (cols[i].ToString() == "Column 2")
                     {
                          bulkCopy.ColumnMappings.Add(i, "Column 2");
                     }

                     if (cols[i].ToString() == "Column 3")
                     {
                          bulkCopy.ColumnMappings.Add(i, "Column 3");
                     }

                    //continued for column mappings...

                }

                bulkCopy.WriteToServer(reader);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...