Массовое копирование C # через OleDBDataReader из большого файла Excel, выбрасывающего из памяти исключение - PullRequest
0 голосов
/ 24 февраля 2019

У меня большой файл Excel (530K строк с большим количеством столбцов).Получается 247 МБ в формате .xlsb.Я пытаюсь импортировать в SQL Server с помощью BulkCopy в C #, однако у меня возникают проблемы, когда у накопителя данных заканчивается нехватка памяти, прежде чем он даже начинает читать файл, как только я запускаю команду ExecuteReader ().

string exlConnString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={_filepath};Extended Properties=\"Excel 12.0;HDR=YES;\"";
string sqlQuery = $"SELECT * FROM [{SheetName}]";
using OleDbConnection conn = new OleDbConnection(_connstring)) {    
   OleDbCommand exlCmd = new OleDbCommand(sqlQuery, conn)
   conn.Open();
   OleDbDataReader dr = exlcmd.ExecuteReader(); <---NEVER GETS PAST THIS LINE BEFORE RUNNING OUT OF MEMORY.
   SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnString);
   bulkCopy.DestinationTable = TableName;
   while(dr.Read()) {
      bulkcopy.WriteToServer(dr);
   }
   dr.Close();
}

Я работаю в режиме x86, потому что я получаю сообщение об ошибке, что База данных ACE не установлена ​​на моем локальном компьютере, и ограничения корпоративной политики не позволяют мне загрузить и установить необходимый файл для запуска его в режиме x64.

Код прекрасно работает, когда я тестирую его на файлах меньшего размера, но не когда я тестирую его на этом файле большего размера, так что это определенно размер файла, вызывающий проблему.Любые предложения или помощь будут оценены.Не имеет большого смысла, что массовая копия исчерпывает память, когда она предназначена для обработки больших наборов данных, что также означает, что размер файла также будет большим ...

И да,Я знаю, что ДОЛЖЕН быть в состоянии импортировать это, используя OPENROWSET или OPENDATASOURCE в SQL Server, но ЭТО ТАКЖЕ выключено, и они не будут включать его, так что это не вариант.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

См. Этот код. Здесь dtExcelData - это переменная, доступная для данных, а da - переменная OleDbDataAdapter.

 string excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={_filepath};Extended Properties='Excel 12.0;HDR=YES';";

                // Create Connection to Excel Workbook
                using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
                {
                    connection.Open();
                    da = new OleDbDataAdapter("Select * FROM [Sheet1$]", connection);    
                    da.Fill(dtExcelData);

                    //store data in sql server database table
                   // below connection string "conString" is I mention in app.config file.(sql server connection string to store data in sql server database)
                    string str = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
                    using (SqlConnection con = new SqlConnection(str))
                    {
                        // Bulk Copy to SQL Server
                        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con))
                        { 
                            bulkCopy.DestinationTableName = "TableName";
                            con.Open();
                            bulkCopy.WriteToServer(dtExcelData);
                            con.Close();
                        }
                    }                        
                    connection.Close();
                }

Отметьте его как ответ, если он полезен для вас.:)

0 голосов
/ 24 февраля 2019

Итак, ваша проблема в следующем.

При попытке ExecuteReader DataReader пытается прочитать все данные из вашего файла Excel в память .Вы можете подумать об этом, как о специалисте, работающем с Excel через OleDbProvider.

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

...