Объект OleDb недействителен или больше не установлен - PullRequest
1 голос
/ 12 июля 2010

Я пытаюсь прочитать файл Excel с помощью OleDb Reader, я не могу отладить код, потому что эта ошибка появляется только на рабочем сервере. Это действительно не имеет смысла для меня, кто-нибудь может мне помочь?

Из журналов появляется ошибка:

System.Data.OleDb.OleDbException: объект недействителен или больше не задан. в System.Data.OleDb.OleDbConnectionInternal.ProcessResults (OleDbHResult hr) в System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset (схема Guid, ограничения Object []) в System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable (схема Guid, ограничения Object []) в System.Data.OleDb.OleDbMetaDataFactory.PrepareCollection (String collectionName, String [] ограничения, соединение DbConnection) в System.Data.ProviderBase.DbMetaDataFactory.GetSchema (соединение DbConnection, String collectionName, String [] ограничения) в System.Data.ProviderBase.DbConnectionInternal.GetSchema (фабрика DbConnectionFactory, DbConnectionPoolGroup poolGroup, DbConnection externalConnection, String collectionName, String [] ограничения) в System.Data.OleDb.OleDbConnection.GetSchema (String collectionName, String [] limittionValues) в System.Data.OleDb.OleDbConnection.GetSchema (String collectionName)

Кроме того, за некоторое время до появления этой ошибки у меня было

System.AccessViolationException: попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена. at System.Data.Common.UnsafeNativeMethods.IDBSchemaRowset.GetRowset (IntPtr pUnkOuter, Guid & rguidSchema, Int32 cRestrictions, Object [] rgRestrictions, Guid & riid, Int32 cPropertySets, IntPtr & IRWSerset), IntPtr и IRG Proset. в System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset (схема Guid, ограничения Object []) в System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable (схема Guid, ограничения Object []) в System.Data.OleDb.OleDbMetaDataFactory.PrepareCollection (String collectionName, String [] ограничения, соединение DbConnection) в System.Data.ProviderBase.DbMetaDataFactory.GetSchema (соединение DbConnection, String collectionName, String [] ограничения) в System.Data.ProviderBase.DbConnectionInternal.GetSchema (фабрика DbConnectionFactory, DbConnectionPoolGroup poolGroup, DbConnection externalConnection, String collectionName, String [] ограничения) в System.Data.OleDb.OleDbConnection.GetSchema (String collectionName, String [] limittionValues) в System.Data.OleDb.OleDbConnection.GetSchema (String collectionName)

исключение также. Я не знаю, связаны ли они. Кто-нибудь может указать мне правильное направление?

Код, который я использую для чтения файла:

            DateTime start = DateTime.Now;
            IEnumerable<string> worksheetNames = GetWorkbookWorksheetNames( connString );
            using ( OleDbConnection connection = new OleDbConnection( connString ) )
            {
                connection.Open();
                foreach ( string worksheetName in worksheetNames )
                {
                    using ( OleDbCommand command = 
                        new OleDbCommand( "SELECT * FROM [" + worksheetName + "]", connection ) )
                    {
                        TEntity entity;
                        using ( OleDbDataReader dataReader = command.ExecuteReader() )
                        {
                            while ( dataReader.Read() )
                            {
                                entity = GetDataFromDataTable( dataReader );

                                if ( entity != null )
                                {
                                    entityList.Add( entity );
                                }
                            }
                        }
                    }
                }
                connection.Close();

GetWorkbookWorksheetNames содержит

private IEnumerable<string> GetWorkbookWorksheetNames( string connString )
    {
        LogUtil.Info( "Getting workbook worksheet names" );
        OleDbConnection _connection = new OleDbConnection( connString );
        List<string> _tableNames = new List<string>();
        try
        {
            // Error Handle
            _connection.Open();
            // Gets the worksheet names
            DataTable _excelSchema = _connection.GetSchema( "Tables" );

            if ( _excelSchema.Rows.Count < 1 )
            {
                throw new FormatException( "The file is in an invalid format. No worksheets were found." );
            }

            foreach ( DataRow _excelSchemaRow in _excelSchema.Rows )
            {
                _tableNames.Add( Regex.Replace( (string)_excelSchemaRow["TABLE_NAME"], "_$", "" ) );
            }
        }
        catch ( OleDbException ex )
        {
            LogUtil.Error( "Could not get Workbook Worksheet names." );
            LogUtil.Error( ex );
            throw ex;
        }
        finally
        {
            _connection.Close();
        }
        return _tableNames;
    }

И я уверен, что ошибка не доходит до GetDataFromDataTable ()

РЕДАКТИРОВАТЬ: я использую строку подключения:

        string connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                        "Data Source=" + filePath + ";" +
                        "Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";";

Я также обнаружил, еще дальше в своих журналах, еще одну ошибку, которая не имела никакого смысла для меня вообще. Я не замечал этого раньше, но это произошло как раз перед AccessViolationException.

Нет сообщения об ошибке, код результата: E_UNEXPECTED (0x8000FFFF). в System.Data.OleDb.OleDbConnectionInternal..ctor (OleDbConnectionString constr, соединение OleDbConnection) в System.Data.OleDb.OleDbConnectionFactory.CreateConnection (параметры DbConnectionOptions, объект poolGroupProviderInfo, пул DbConnectionPool, DbConnection owningObject) в System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection (DbConnection owningConnection, DbConnectionPoolGroup poolGroup) в System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection owningConnection) в System.Data.ProviderBase.DbConnectionClosed.OpenConnection (DbConnection externalConnection, DbConnectionFactory connectionFactory) в System.Data.OleDb.OleDbConnection.Open ()в REMEC.Library.WatcherServiceCommon.ExcelParserService`1.GetWorkbookWorksheetNames (String connString) в

И при моделировании этой ошибки в ходе теста поток никогда не останавливается, заставляя меня предположить, что эта ошибка фактически не закрываетсясоединение даже после явного закрытия его в моем предложении finally.

Извините за длинные блоки кода / текста

1 Ответ

2 голосов
/ 12 июля 2010

Возможно - проблема со значением ConnStr;
Попробуйте это:

private String [] GetExcelSheetNames (строка excelFile) { OleDbConnection objConn = null; System.Data.DataTable dt = null;

  try
  {
    // Connection String. Change the excel file to the file you
    // will search.

    String connString = "Provider=Microsoft.Jet.OLEDB.4.0;" + 
        "Data Source=" + excelFile + ";Extended Properties=Excel 8.0;";
    // Create connection object by using the preceding connection string.

    objConn = new OleDbConnection(connString);
    // Open connection with the database.

    objConn.Open();

    // Get the data table containg the schema guid.    
    dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

    if(dt == null)
    {
      return null;
    }

    String[] excelSheets = new String[dt.Rows.Count];
    int i = 0;

    // Add the sheet name to the string array.

    foreach(DataRow row in dt.Rows)
    {
      excelSheets[i] = row["TABLE_NAME"].ToString();
      i++;
    }

    // Loop through all of the sheets if you want too...

    for(int j=0; j < excelSheets.Length; j++)
    {
      // Query each excel sheet.

    }

    return excelSheets;
  }
  catch(Exception ex)
  {
    return null;
  }
  finally
  {
    // Clean up.

    if(objConn != null)
    {
      objConn.Close();
      objConn.Dispose();
    }
    if(dt != null)
    {
      dt.Dispose();
    }
  }
}
...