【问题标题】:OleDb Object Invalid or No Longer SetOleDb 对象无效或不再设置
【发布时间】:2010-07-13 06:42:35
【问题描述】:

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

从日志中显示的错误如下:

System.Data.OleDb.OleDbException:对象无效或不再设置。 在 System.Data.OleDb.OleDbConnectionInternal.ProcessResults(OleDbHResult 小时) 在 System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset(Guid 架构,对象 [] 限制) 在 System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable(Guid 架构,对象 [] 限制) 在 System.Data.OleDb.OleDbMetaDataFactory.PrepareCollection(字符串集合名称,字符串 [] 限制,DbConnection 连接) 在 System.Data.ProviderBase.DbMetaDataFactory.GetSchema(DbConnection 连接,字符串集合名称,字符串 [] 限制) 在 System.Data.ProviderBase.DbConnectionInternal.GetSchema(DbConnectionFactory 工厂,DbConnectionPoolGroup poolGroup,DbConnection outerConnection,String collectionName,String[] 限制) 在 System.Data.OleDb.OleDbConnection.GetSchema(字符串集合名称,字符串 [] 限制值) 在 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(字符串集合名称,字符串 [] 限制,DbConnection 连接) 在 System.Data.ProviderBase.DbMetaDataFactory.GetSchema(DbConnection 连接,字符串集合名称,字符串 [] 限制) 在 System.Data.ProviderBase.DbConnectionInternal.GetSchema(DbConnectionFactory 工厂,DbConnectionPoolGroup poolGroup,DbConnection outerConnection,String collectionName,String[] 限制) 在 System.Data.OleDb.OleDbConnection.GetSchema(字符串集合名称,字符串 [] 限制值) 在 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 常量,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 outerConnection,DbConnectionFactory connectionFactory) 在 System.Data.OleDb.OleDbConnection.Open() 在 REMEC.Library.WatcherServiceCommon.ExcelParserService`1.GetWorkbookWorksheetNames(String connString) in

在测试中模拟这个错误时,线程永远不会停止,这让我假设即使在我的 finally 子句中明确关闭连接之后,所述错误也不会真正关闭连接。

抱歉,代码/文本太长了

【问题讨论】:

    标签: excel exception oledb


    【解决方案1】:

    可能 - ConnStr 值问题;
    试试这个:

    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();
        }
      }
    }
    

    【讨论】:

    • 使用数据表会提高它在数据读取器上工作的机会吗? (还添加了一些我刚刚发现的有关该错误的详细信息。)
    • 你知道我在 Excel 中使用数据表已经很长时间了......不确定它是否会提高机会......只要知道它适用于数据表方法。在处理针对 excel 的复杂查询时,我从来没有使用过我喜欢最简单的方法的数据阅读器。 excel工作簿中发生的很多事情都需要担心。让我知道结果如何。不管你的结果是什么,或者你追求什么,我都很感兴趣。
    • 我需要我能获得的每一点性能提升,所以我选择了数据读取器路线。事实证明,这根本不是那部分,因为是 _connection.GetSchema() 导致了所有错误。根源确实是由一个特定的 excel 文件引起的“E_UNEXPECTED”错误。由于时间限制,我还没有找到解决方法,不得不求助于寻找外部库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多