OleDb对象无效或不再设置

时间:2010-07-12 04:28:20

标签: excel exception oledb

我正在尝试使用OleDb Reader读取excel文件,我无法调试代码,因为此错误仅出现在生产服务器上。这对我来说真的没有意义,任何人都可以帮助我吗?

从日志中出现错误:

  

System.Data.OleDb.OleDbException:对象无效或不再设置。      在System.Data.OleDb.OleDbConnectionInternal.ProcessResults(OleDbHResult hr)      在System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset(Guid架构,对象[]限制)      在System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable(Guid架构,对象[]限制)      在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 outerConnection,String collectionName,String []限制)      at System.Data.OleDb.OleDbConnection.GetSchema(String collectionName,String [] restrictionValues)      在System.Data.OleDb.OleDbConnection.GetSchema(String collectionName)

此外,在此错误出现前一段时间,我有一个

  

System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。      在System.Data.Common.UnsafeNativeMethods.IDBSchemaRowset.GetRowset(IntPtr pUnkOuter,Guid& rguidSchema,Int32 cRestrictions,Object [] rgRestrictions,Guid& riid,Int32 cPropertySets,IntPtr rgPropertySets,IRowset& ppRowset)      在System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset(Guid架构,对象[]限制)      在System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable(Guid架构,对象[]限制)      在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 outerConnection,String collectionName,String []限制)      at System.Data.OleDb.OleDbConnection.GetSchema(String collectionName,String [] restrictionValues)      在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选项,Object 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 outerConnection,DbConnectionFactory connectionFactory)      在System.Data.OleDb.OleDbConnection.Open()      在REMEC.Library.WatcherServiceCommon.ExcelParserService`1.GetWorkbookWorksheetNames(String connString)in

在测试中模拟此错误时,线程永远不会停止,让我假设即使在我的finally子句中明确关闭它之后,所述错误实际上也没有关闭连接。

对于长代码/文本块

抱歉

1 个答案:

答案 0 :(得分:2)

可能 - 康德价值问题;
试试这个:

private String [] GetExcelSheetNames(string 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();
    }
  }
}