2010-07-12 111 views
1

我想读取使用OleDb读取器的Excel文件,我无法调试代码,因为此错误只出现在生产服务器上。这对我来说真的没有意义,有人能帮助我吗?OleDb对象无效或不再设置

从错误中出来的日志:

System.Data.OleDb.OleDbException:对象无效或不再设置。 (System.Data.OleDb.OleDbConnection.Internal.ProcessResults(OleDbHResult hr) at System.Data.OleDb.OleDbConnectionInternal.GetSchemaRowset(Guid schema,Object [] constraints) at System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable(Guid schema,对象[]限制) at System.Data.OleDb.OleDbMetaDataFactory.PrepareCollection(String collectionName,String [] constraints,DbConnection connection) at System.Data.ProviderBase.DbMetaDataFactory.GetSchema(DbConnection connection,String collectionName,String [] constraints ) at System.Data.ProviderBase.DbConnectionInternal.GetSchema(DbConnectionFactory factory,DbConnectionPoolGroup poolGroup,DbConnection outerConnection,String collectionName,String [] restrictions) at System.Data.OleDb.OleDbConnection.GetSchema(字符串集合名,字符串[] restrictionValues) 在System.Data.OleDb.OleDbConnection.GetSchema(字符串集合名)

此外,一会儿这个错误出现之前,我有一个

系统。 AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。 在System.Data.Common.UnsafeNativeMethods.IDBSchemaRowset.GetRowset(IntPtr的pUnkOuter,的Guid & rguidSchema,的Int32 cRestrictions,对象[] rgRestrictions,的Guid & RIID,的Int32 cPropertySets,IntPtr的rgPropertySets,的IRowset & ppRowset) 在System.Data.OleDb OleDbConnectionInternal.GetSchemaRowset(Guid schema,Object [] constraints) at System.Data.OleDb.OleDbMetaDataFactory.PrepareCollection(String collectionName,String [ ]限制,DbConnection连接) at System.Data.ProviderBase.DbMetaDataFactory.GetSchema(DbConnection connection,String collectionName,String [] restrictions) at System.Data.ProviderBase.DbCo nnectionInternal.GetSchema(DbConnectionFactory factory,DbConnectionPoolGroup poolGroup,DbConnection outerConnection,String collectionName,String [] constraints) at System.Data.OleDb.OleDbConnection.GetSchema(String collectionName,String [] restrictionValues) at 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在System.Data.OleDb.OleDbConnectionFactory.CreateConnection(OleDbConnectionString构造,OleDbConnection的连接) (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() at REMEC.Library.WatcherServiceCommon.ExcelParserService`1.GetWorkbookWorksheetNames(在

虽然测试下模拟该错误字符串CONNSTRING),线程永远不会停止,使我认为说错误实际上并不关闭连接后也显式关闭它在我的最后条款。

对不起,长块代码/文本

回答

2

可能 - ConnStr值问题;
尝试此:

私有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(); 
    } 
    } 
} 
+0

使用数据表会提高它在数据读取器上工作的几率吗? (还添加了一些我刚刚发现的有关错误的更多细节。) – Jonn 2010-07-12 04:48:53

+0

你知道我已经使用excel的数据表很长一段时间了......不知道它是否提高了机会......只知道它可以与数据表一起工作方法。我从来没有走过使用数据读取器的路线。我喜欢在处理针对excel的复杂查询时最简单的方法。要在excel工作簿上继续担心,因为它是。 让我知道这是如何结果。无论你的结果如何,或者你追求什么,我都很感兴趣。 – 2010-07-13 00:11:57

+0

我需要性能提升的每一点,我可以得到所以我选择了datareader路由。 原来,这根本不是那个部分,因为它是_connection.GetSchema(),它导致了所有的错误。根确实是由一个特定的excel文件引起的“E_UNEXPECTED”错误。我还没有找到解决方法,并且由于时间限制,不得不求助于寻找外部库。 – Jonn 2010-07-13 02:57:24